Compare commits
	
		
			14 Commits
		
	
	
		
			0278540fb2
			...
			v122092572
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | f4db02521d | ||
|  | 01763556b1 | ||
|  | e2411c00d8 | ||
|  | 0473a5f7bc | ||
|  | d0d6a4378c | ||
|  | 1dfa3c9f07 | ||
|  | 815f00e764 | ||
| bdc77ab8ef | |||
| 6bd06cb458 | |||
|  | e9e8bee6c9 | ||
|  | ff6038dbd4 | ||
|  | 8146cff011 | ||
|  | fc4c48dd12 | ||
|  | 94f1ec943c | 
							
								
								
									
										104
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								.drone.yml
									
									
									
									
									
								
							| @@ -1,21 +1,117 @@ | ||||
| kind: pipeline | ||||
| type: docker | ||||
| name: android | ||||
| name: test | ||||
|  | ||||
| steps: | ||||
|   - name: code-analysis | ||||
|   - name: AnylyseBuildTest | ||||
|     image: mingc/android-build-box:latest | ||||
|     failure: ignore | ||||
|     commands: | ||||
|       - ls -la | ||||
|       - echo "---------------------------------------------------------" | ||||
|       - echo "Analysing..." | ||||
|       - ./gradlew sonarqube -Dsonar.projectKey=RFS2 -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" | ||||
|       - echo "---------------------------------------------------------" | ||||
|       - echo "Building..." | ||||
|       - ./gradlew :androidApp:build -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false | ||||
|       - echo "---------------------------------------------------------" | ||||
|       - echo "Testing..." | ||||
|       - echo "---------------------------------------------------------" | ||||
|     environment: | ||||
|       SONAR_HOST_URL: | ||||
|         from_secret: sonarScannerHostUrl | ||||
|       SONAR_LOGIN: | ||||
|         from_secret: sonarScannerLogin | ||||
| trigger: | ||||
|   event: | ||||
|     - push | ||||
|     - pull_request | ||||
|  | ||||
| --- | ||||
| kind: pipeline | ||||
| type: docker | ||||
| name: Publish | ||||
|  | ||||
| steps: | ||||
|   - name: createTag | ||||
|     image: ubuntu:latest | ||||
|     commands: | ||||
|       - apt-get update && apt-get install -y git | ||||
|       - ./build.sh --publish --from-ci | ||||
|       - git remote add pushing https://$GITEA_USR:$GITEA_PASS@gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform.git | ||||
|       - git push pushing --tags | ||||
|     environment: | ||||
|       GITEA_USR: | ||||
|         from_secret: giteaUsr | ||||
|       GITEA_PASS: | ||||
|         from_secret: giteaPass | ||||
|  | ||||
|   - name: scpFiles | ||||
|     image: appleboy/drone-scp | ||||
|     settings: | ||||
|       host: amine-louveau.fr | ||||
|       username: ubuntu | ||||
|       key: | ||||
|         from_secret: privateKey | ||||
|       port: 22 | ||||
|       target: /home/ubuntu/ | ||||
|       source: version.txt | ||||
|  | ||||
|   - name: deploy | ||||
|     image: appleboy/drone-ssh | ||||
|     settings: | ||||
|       host: amine-louveau.fr | ||||
|       user: ubuntu | ||||
|       key: | ||||
|         from_secret: privateKey | ||||
|       command_timeout: 2m | ||||
|       script: | ||||
|         - cd /home/ubuntu | ||||
|         - sudo rm -rf /var/www/amine/version.txt | ||||
|         - sudo chown www-data:www-data ./version.txt | ||||
|         - sudo mv version.txt /var/www/amine/ | ||||
|  | ||||
| trigger: | ||||
|   event: | ||||
|     - promote | ||||
|   target: | ||||
|     - production | ||||
|  | ||||
| --- | ||||
| kind: pipeline | ||||
| type: docker | ||||
| name: Release | ||||
|  | ||||
| steps: | ||||
|   - name: build | ||||
|     image: mingc/android-build-box:latest | ||||
|     commands: | ||||
|       - ./gradlew  :androidApp:build -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false | ||||
|       - echo "Generate APK" | ||||
|       - ./gradlew :androidApp:assembleGithubConfigRelease -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false | ||||
|       - echo "---------------------------------------------------------" | ||||
|       - echo "Get Key" | ||||
|       - wget https://amine-louveau.fr/key | ||||
|       - echo "---------------------------------------------------------" | ||||
|       - echo "Zipalign" | ||||
|       - $ANDROID_HOME/build-tools/31.0.0/zipalign -f -v 4 androidApp/build/outputs/apk/githubConfig/release/androidApp-githubConfig-release-unsigned.apk androidApp/build/outputs/apk/githubConfig/release/android-prod-released-ziped.apk | ||||
|       - echo "---------------------------------------------------------" | ||||
|       - echo "Sign" | ||||
|       - $ANDROID_HOME/build-tools/31.0.0/apksigner sign -v --out signed.apk --ks ./key --ks-key-alias $YOUR_KEY_ALIAS --ks-pass pass:$YOUR_KEYSTORE_PASSWORD --v1-signing-enabled true --v2-signing-enabled true androidApp/build/outputs/apk/githubConfig/release/android-prod-released-ziped.apk | ||||
|       - echo "---------------------------------------------------------" | ||||
|       - echo "Verify" | ||||
|       - $ANDROID_HOME/build-tools/31.0.0/apksigner verify signed.apk | ||||
|     environment: | ||||
|       YOUR_KEYSTORE_PASSWORD: | ||||
|         from_secret: keyPass | ||||
|       YOUR_KEY_ALIAS: | ||||
|         from_secret: keyAlias | ||||
|  | ||||
|   - name: gitea_release | ||||
|     image: plugins/gitea-release | ||||
|     settings: | ||||
|       api_key: | ||||
|         from_secret: giteaAPI | ||||
|       base_url: https://gitea.amine-louveau.fr | ||||
|       files: signed.apk | ||||
| trigger: | ||||
|   event: | ||||
|     - tag | ||||
							
								
								
									
										11
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -1,3 +1,14 @@ | ||||
| # V2/Multiplatform rewrite | ||||
|  | ||||
| **v1** | ||||
|  | ||||
| - The app has the same functionalities as before. | ||||
|  | ||||
|  | ||||
| -------------------------------------------------------------------- | ||||
|                                                                        | ||||
| # Old version changes | ||||
|  | ||||
| **1.7.x** | ||||
|  | ||||
| - Hiding tags with 0 articles | ||||
|   | ||||
| @@ -93,7 +93,7 @@ android { | ||||
|     } | ||||
|     flavorDimensions.add("build") | ||||
|     productFlavors { | ||||
|         create("github") { | ||||
|         create("githubConfig") { | ||||
|             versionNameSuffix = "-github" | ||||
|             dimension = "build" | ||||
|         } | ||||
|   | ||||
							
								
								
									
										31
									
								
								androidApp/proguard-rules.pro
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								androidApp/proguard-rules.pro
									
									
									
									
										vendored
									
									
								
							| @@ -55,11 +55,38 @@ | ||||
|   public *; | ||||
| } | ||||
|  | ||||
| -dontwarn com.anupcowkur.reservoir.** | ||||
|  | ||||
| -dontwarn javax.annotation.** | ||||
|  | ||||
| -keep class android.support.v7.widget.SearchView { *; } | ||||
|  | ||||
| # maybe remove later ? | ||||
| -keep class * extends androidx.fragment.app.Fragment | ||||
|  | ||||
|  | ||||
| # Keep `Companion` object fields of serializable classes. | ||||
| # This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects. | ||||
| -if @kotlinx.serialization.Serializable class ** | ||||
| -keepclassmembers class <1> { | ||||
|    static <1>$Companion Companion; | ||||
| } | ||||
|  | ||||
| # Keep `serializer()` on companion objects (both default and named) of serializable classes. | ||||
| -if @kotlinx.serialization.Serializable class ** { | ||||
|    static **$* *; | ||||
| } | ||||
| -keepclassmembers class <2>$<3> { | ||||
|    kotlinx.serialization.KSerializer serializer(...); | ||||
| } | ||||
|  | ||||
| # Keep `INSTANCE.serializer()` of serializable objects. | ||||
| -if @kotlinx.serialization.Serializable class ** { | ||||
|    public static ** INSTANCE; | ||||
| } | ||||
| -keepclassmembers class <1> { | ||||
|    public static <1> INSTANCE; | ||||
|    kotlinx.serialization.KSerializer serializer(...); | ||||
| } | ||||
|  | ||||
| # @Serializable and @Polymorphic are used at runtime for polymorphic serialization. | ||||
| -keepattributes RuntimeVisibleAnnotations,AnnotationDefault | ||||
|  | ||||
|   | ||||
| @@ -1,11 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # NOTE: This is copy/pasted in jenkins | ||||
|  | ||||
| rm -f version.txt | ||||
| printf "versionName=$1-github\nversionCode=$1" >> version.txt | ||||
|  | ||||
| # You'll need to change server as your server and define a VERSION_PATH. | ||||
| scp version.txt server:$VERSION_PATH | ||||
|  | ||||
| rm version.txt | ||||
| @@ -1,18 +1,22 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     package="bou.amine.apps.readerforselfossv2.android"> | ||||
|  | ||||
|     <uses-permission android:name="android.permission.INTERNET" /> | ||||
|     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> | ||||
|  | ||||
|     <application | ||||
|         android:allowBackup="false" | ||||
|         android:fullBackupContent="false" | ||||
|         tools:replace="android:allowBackup" | ||||
|         android:name=".MyApp" | ||||
|         android:allowBackup="true" | ||||
|         android:icon="@mipmap/ic_launcher" | ||||
|         android:label="@string/app_name" | ||||
|         android:supportsRtl="true" | ||||
|         android:networkSecurityConfig="@xml/network_security_config" | ||||
|         android:theme="@style/NoBar"> | ||||
|         android:theme="@style/NoBar" | ||||
|         android:dataExtractionRules="@xml/data_extraction_rules"> | ||||
|         <activity | ||||
|             android:name=".MainActivity" | ||||
|             android:theme="@style/SplashTheme" | ||||
|   | ||||
| @@ -11,6 +11,7 @@ import android.view.MenuItem | ||||
| import android.view.View | ||||
| import android.widget.ImageView | ||||
| import android.widget.Toast | ||||
| import androidx.activity.result.contract.ActivityResultContracts | ||||
| import androidx.appcompat.app.ActionBarDrawerToggle | ||||
| import androidx.appcompat.app.AlertDialog | ||||
| import androidx.appcompat.app.AppCompatActivity | ||||
| @@ -49,14 +50,12 @@ import com.mikepenz.materialdrawer.holder.ColorHolder | ||||
| import com.mikepenz.materialdrawer.holder.StringHolder | ||||
| import com.mikepenz.materialdrawer.model.DividerDrawerItem | ||||
| import com.mikepenz.materialdrawer.model.PrimaryDrawerItem | ||||
| import com.mikepenz.materialdrawer.model.ProfileDrawerItem | ||||
| import com.mikepenz.materialdrawer.model.SecondaryDrawerItem | ||||
| import com.mikepenz.materialdrawer.model.interfaces.* | ||||
| import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader | ||||
| import com.mikepenz.materialdrawer.util.DrawerImageLoader | ||||
| import com.mikepenz.materialdrawer.util.addStickyFooterItem | ||||
| import com.mikepenz.materialdrawer.util.updateBadge | ||||
| import com.mikepenz.materialdrawer.widget.AccountHeaderView | ||||
| import kotlinx.coroutines.CoroutineScope | ||||
| import kotlinx.coroutines.Dispatchers | ||||
| import kotlinx.coroutines.launch | ||||
| @@ -64,12 +63,10 @@ import org.kodein.di.DIAware | ||||
| import org.kodein.di.android.closestDI | ||||
| import org.kodein.di.instance | ||||
| import java.util.concurrent.TimeUnit | ||||
| import kotlin.concurrent.thread | ||||
|  | ||||
|  | ||||
| class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAware { | ||||
|  | ||||
|     private val SETTINGS_ACTIVITY: Int = 101111 | ||||
|     private val DRAWER_ID_TAGS = 100101L | ||||
|     private val DRAWER_ID_HIDDEN_TAGS = 101100L | ||||
|     private val DRAWER_ID_SOURCES = 100110L | ||||
| @@ -96,6 +93,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar | ||||
|  | ||||
|     private lateinit var tagsBadge: Map<Long, Int> | ||||
|  | ||||
|     private val settingsLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { | ||||
|         appSettingsService.refreshUserSettings() | ||||
|     } | ||||
|  | ||||
|     override val di by closestDI() | ||||
|     private val repository : Repository by instance() | ||||
|     private val appSettingsService : AppSettingsService by instance() | ||||
| @@ -137,7 +138,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar | ||||
|         customTabActivityHelper = CustomTabActivityHelper() | ||||
|  | ||||
|         handleBottomBar() | ||||
|         handleDrawer() | ||||
|         initDrawer() | ||||
|  | ||||
|         handleSwipeRefreshLayout() | ||||
|  | ||||
| @@ -147,7 +148,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar | ||||
|         CoroutineScope(Dispatchers.Main).launch { | ||||
|             repository.tryToCacheItemsAndGetNewOnes() | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     private fun handleSwipeRefreshLayout() { | ||||
| @@ -323,17 +323,17 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar | ||||
|         scoop.update(Toppings.PRIMARY_DARK.value, appColors.colorPrimaryDark) | ||||
|     } | ||||
|  | ||||
|     private fun handleDrawer() { | ||||
|     private fun initDrawer() { | ||||
|         DrawerImageLoader.init(object : AbstractDrawerImageLoader() { | ||||
|             override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) { | ||||
|                 Glide.with(this@HomeActivity) | ||||
|                         .asBitmap() | ||||
|                         .load(uri) | ||||
|                         .apply(RequestOptions() | ||||
|                                 .placeholder(R.mipmap.ic_launcher) | ||||
|                                 .fallback(R.mipmap.ic_launcher) | ||||
|                                 .fitCenter()) | ||||
|                         .into(imageView) | ||||
|                     .asBitmap() | ||||
|                     .load(uri) | ||||
|                     .apply(RequestOptions() | ||||
|                         .placeholder(R.mipmap.ic_launcher) | ||||
|                         .fallback(R.mipmap.ic_launcher) | ||||
|                         .fitCenter()) | ||||
|                     .into(imageView) | ||||
|             } | ||||
|  | ||||
|             override fun cancel(imageView: ImageView) { | ||||
| @@ -362,285 +362,31 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar | ||||
|  | ||||
|         binding.drawerContainer.addDrawerListener(drawerListener) | ||||
|  | ||||
|         binding.mainDrawer.addStickyFooterItem( | ||||
|             PrimaryDrawerItem().apply { | ||||
|                 nameRes = R.string.drawer_report_bug | ||||
|                 iconRes = R.drawable.ic_bug_report_black_24dp | ||||
|                 isIconTinted = true | ||||
|                 onDrawerItemClickListener = { _, _, _ -> | ||||
|                     val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(AppSettingsService.trackerUrl)) | ||||
|                     startActivity(browserIntent) | ||||
|                     false | ||||
|                 } | ||||
|             }) | ||||
|  | ||||
|         binding.mainDrawer.addStickyFooterItem( | ||||
|             PrimaryDrawerItem().apply { | ||||
|                 nameRes = R.string.title_activity_settings | ||||
|                 iconRes = R.drawable.ic_settings_black_24dp | ||||
|                 isIconTinted = true | ||||
|                 onDrawerItemClickListener = { _, _, _ -> | ||||
|                     startActivityForResult(Intent(this@HomeActivity, SettingsActivity::class.java), SETTINGS_ACTIVITY) | ||||
|                     false | ||||
|                 } | ||||
|             }) | ||||
|  | ||||
|         if (appSettingsService.isDisplayAccountHeaderEnabled()) { | ||||
|             AccountHeaderView(this).apply { | ||||
|                 attachToSliderView(binding.mainDrawer) | ||||
|                 addProfiles( | ||||
|                     ProfileDrawerItem().apply { | ||||
|                         nameText = appSettingsService.getBaseUrl() | ||||
|                         setBackgroundResource(R.drawable.bg) | ||||
|                         iconRes = R.mipmap.ic_launcher | ||||
|                         selectionListEnabledForSingleProfile = false | ||||
|                     } | ||||
|                 ) | ||||
|             } | ||||
|         // Sticky items | ||||
|         addStickyPrimaryItem(R.string.drawer_report_bug, R.drawable.ic_bug_report_black_24dp) { _, _, _ -> | ||||
|             val browserIntent = | ||||
|                 Intent(Intent.ACTION_VIEW, Uri.parse(AppSettingsService.trackerUrl)) | ||||
|             startActivity(browserIntent) | ||||
|             false | ||||
|         } | ||||
|         addStickyPrimaryItem(R.string.title_activity_settings, R.drawable.ic_settings_black_24dp) { _, _, _ -> | ||||
|             settingsLauncher.launch(Intent(this, SettingsActivity::class.java)) | ||||
|             false | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // TODO: refactor this. | ||||
|     // TODO: use updateSources | ||||
|     private fun addStickyPrimaryItem(name: Int, icon: Int, clickListener: ((v: View?, item: IDrawerItem<*>, position: Int) -> Boolean)?) { | ||||
|         binding.mainDrawer.addStickyFooterItem( | ||||
|             PrimaryDrawerItem().apply { | ||||
|                 nameRes = name | ||||
|                 iconRes = icon | ||||
|                 isIconTinted = true | ||||
|                 onDrawerItemClickListener = clickListener | ||||
|             }) | ||||
|     } | ||||
|  | ||||
|     private fun handleDrawerItems() { | ||||
|         tagsBadge = emptyMap() | ||||
|         fun handleDrawerData(maybeDrawerData: DrawerData?, loadedFromCache: Boolean = false) { | ||||
|             fun createDrawerItem( | ||||
|                 it: SelfossModel.Tag | ||||
|             ) { | ||||
|                 val gd = GradientDrawable() | ||||
|                 val gdColor = try { | ||||
|                     Color.parseColor(it.color) | ||||
|                 } catch (e: IllegalArgumentException) { | ||||
|                     appColors.colorPrimary | ||||
|                 } | ||||
|  | ||||
|                 gd.setColor(gdColor) | ||||
|                 gd.shape = GradientDrawable.RECTANGLE | ||||
|                 gd.setSize(30, 30) | ||||
|                 gd.cornerRadius = 30F | ||||
|  | ||||
|                 val drawerItem = PrimaryDrawerItem() | ||||
|                     .apply { | ||||
|                         nameText = it.tag.getHtmlDecoded() | ||||
|                         identifier = it.tag.longHash() | ||||
|                         iconDrawable = gd | ||||
|                         badgeStyle = BadgeStyle().apply { | ||||
|                             textColor = ColorHolder.fromColor(Color.WHITE) | ||||
|                             color = ColorHolder.fromColor(appColors.colorAccent) | ||||
|                         } | ||||
|                         onDrawerItemClickListener = { _, _, _ -> | ||||
|                             repository.tagFilter = it | ||||
|                             repository.sourceFilter = null | ||||
|                             getElementsAccordingToTab() | ||||
|                             fetchOnEmptyList() | ||||
|                             false | ||||
|                         } | ||||
|                     } | ||||
|                 if (it.unread > 0) { | ||||
|                     drawerItem.badgeText = it.unread.toString() | ||||
|                 } | ||||
|  | ||||
|                 binding.mainDrawer.itemAdapter.add(drawerItem) | ||||
|             } | ||||
|  | ||||
|             fun handleTags(maybeTags: List<SelfossModel.Tag>?) { | ||||
|                 if (maybeTags == null) { | ||||
|                     if (loadedFromCache) { | ||||
|                         binding.mainDrawer.itemAdapter.add( | ||||
|                             SecondaryDrawerItem() | ||||
|                                 .apply { nameRes = R.string.drawer_error_loading_tags; isSelectable = false } | ||||
|                         ) | ||||
|                     } | ||||
|                 } else { | ||||
|                     val filteredTags = maybeTags | ||||
|                         .filterNot { appSettingsService.getHiddenTags().contains(it.tag) } | ||||
|                         .sortedBy { it.unread == 0 } | ||||
|                     tagsBadge = filteredTags.map { | ||||
|                         createDrawerItem(it) | ||||
|  | ||||
|                         (it.tag.longHash() to it.unread) | ||||
|                     }.toMap() | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             fun handleHiddenTags(maybeTags: List<SelfossModel.Tag>?) { | ||||
|                 if (maybeTags == null) { | ||||
|                     if (loadedFromCache) { | ||||
|                         binding.mainDrawer.itemAdapter.add( | ||||
|                             SecondaryDrawerItem().apply { | ||||
|                                 nameRes = R.string.drawer_error_loading_tags | ||||
|                                 isSelectable = false | ||||
|                             } | ||||
|                         ) | ||||
|                     } | ||||
|                 } else { | ||||
|                     val filteredHiddenTags: List<SelfossModel.Tag> = | ||||
|                         maybeTags.filter { appSettingsService.getHiddenTags().contains(it.tag) } | ||||
|                     tagsBadge = filteredHiddenTags.map { | ||||
|                         createDrawerItem(it) | ||||
|  | ||||
|                         (it.tag.longHash() to it.unread) | ||||
|                     }.toMap() | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             fun handleSources(maybeSources: List<SelfossModel.Source>?) { | ||||
|                 if (maybeSources == null) { | ||||
|                     if (loadedFromCache) { | ||||
|                         binding.mainDrawer.itemAdapter.add( | ||||
|                             SecondaryDrawerItem().apply { | ||||
|                                 nameRes = R.string.drawer_error_loading_sources | ||||
|                                 isSelectable = false | ||||
|                             } | ||||
|                         ) | ||||
|                     } | ||||
|                 } else { | ||||
|                     for (source in maybeSources) { | ||||
|                         val item = PrimaryDrawerItem().apply { | ||||
|                             nameText = source.title.getHtmlDecoded() | ||||
|                             identifier = source.id.toLong() | ||||
|                             iconUrl = source.getIcon(repository.baseUrl) | ||||
|                             onDrawerItemClickListener = { _,_,_ -> | ||||
|                                 repository.sourceFilter = source | ||||
|                                 repository.tagFilter = null | ||||
|                                 getElementsAccordingToTab() | ||||
|                                 fetchOnEmptyList() | ||||
|                                 false | ||||
|                             } | ||||
|                         } | ||||
|                         binding.mainDrawer.itemAdapter.add(item) | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             binding.mainDrawer.itemAdapter.clear() | ||||
|             if (maybeDrawerData != null) { | ||||
|                 binding.mainDrawer.itemAdapter.add( | ||||
|                     SecondaryDrawerItem().apply { | ||||
|                         nameRes = R.string.drawer_item_filters | ||||
|                         isSelectable = false | ||||
|                         identifier = DRAWER_ID_FILTERS | ||||
|                         badgeRes = R.string.drawer_action_clear | ||||
|                         onDrawerItemClickListener = { _,_,_ -> | ||||
|                             repository.sourceFilter = null | ||||
|                             repository.tagFilter = null | ||||
|                             binding.mainDrawer.setSelectionAtPosition(-1) | ||||
|                             getElementsAccordingToTab() | ||||
|                             fetchOnEmptyList() | ||||
|                             false | ||||
|                         } | ||||
|                     } | ||||
|                 ) | ||||
|                 if (appSettingsService.getHiddenTags().isNotEmpty()) { | ||||
|                     binding.mainDrawer.itemAdapter.add( | ||||
|                         DividerDrawerItem(), | ||||
|                         SecondaryDrawerItem().apply { | ||||
|                             nameRes = R.string.drawer_item_hidden_tags | ||||
|                             identifier = DRAWER_ID_HIDDEN_TAGS | ||||
|                             isSelectable = false | ||||
|                         } | ||||
|                     ) | ||||
|                     handleHiddenTags(maybeDrawerData.tags) | ||||
|                 } | ||||
|                 binding.mainDrawer.itemAdapter.add( | ||||
|                     DividerDrawerItem(), | ||||
|                     SecondaryDrawerItem().apply { | ||||
|                         nameRes = R.string.drawer_item_tags | ||||
|                         identifier = DRAWER_ID_TAGS | ||||
|                         isSelectable = false | ||||
|                     } | ||||
|                 ) | ||||
|                 handleTags(maybeDrawerData.tags) | ||||
|                 binding.mainDrawer.itemAdapter.add( | ||||
|                     DividerDrawerItem(), | ||||
|                     SecondaryDrawerItem().apply { | ||||
|                         nameRes = R.string.drawer_item_sources | ||||
|                         identifier = DRAWER_ID_SOURCES | ||||
|                         isSelectable = false | ||||
|                         badgeRes = R.string.drawer_action_edit | ||||
|                         onDrawerItemClickListener = { v,_,_ -> | ||||
|                             startActivity(Intent(v!!.context, SourcesActivity::class.java)) | ||||
|                             false | ||||
|                         } | ||||
|                     } | ||||
|                 ) | ||||
|                 handleSources(maybeDrawerData.sources) | ||||
|                 binding.mainDrawer.itemAdapter.add( | ||||
|                     DividerDrawerItem(), | ||||
|                     PrimaryDrawerItem().apply { | ||||
|                         nameRes = R.string.action_about | ||||
|                         isSelectable = false | ||||
|                         iconRes = R.drawable.ic_info_outline_white_24dp | ||||
|                         isIconTinted = true | ||||
|                         onDrawerItemClickListener = { _,_,_ -> | ||||
|                             LibsBuilder() | ||||
|                                 .withAboutIconShown(true) | ||||
|                                 .withAboutVersionShown(true) | ||||
|                                 .start(this@HomeActivity) | ||||
|                             false | ||||
|                         } | ||||
|                     } | ||||
|                 ) | ||||
|  | ||||
|                 if (!loadedFromCache) { | ||||
|                     if (maybeDrawerData.tags != null) { | ||||
|                         thread { | ||||
|                             repository.resetDBTagsWithData(maybeDrawerData.tags) | ||||
|                         } | ||||
|                     } | ||||
|                     if (maybeDrawerData.sources != null) { | ||||
|                         thread { | ||||
|                             repository.resetDBSourcesWithData(maybeDrawerData.sources) | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 if (!loadedFromCache) { | ||||
|                     binding.mainDrawer.itemAdapter.add( | ||||
|                         PrimaryDrawerItem().apply { | ||||
|                             nameRes = R.string.no_tags_loaded | ||||
|                             identifier = DRAWER_ID_TAGS | ||||
|                             isSelectable = false | ||||
|                         }, | ||||
|                         PrimaryDrawerItem().apply { | ||||
|                             nameRes = R.string.no_sources_loaded | ||||
|                             identifier = DRAWER_ID_SOURCES | ||||
|                             isSelectable = false | ||||
|                         } | ||||
|                     ) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         fun drawerApiCalls(maybeDrawerData: DrawerData?) { | ||||
|             var tags: List<SelfossModel.Tag>? = null | ||||
|             var sources: List<SelfossModel.Source>? | ||||
|  | ||||
|             fun sourcesApiCall() { | ||||
|                 CoroutineScope(Dispatchers.Main).launch { | ||||
|                     val response = repository.getSources() | ||||
|                     if (response != null) { | ||||
|                         sources = response | ||||
|                         val apiDrawerData = DrawerData(tags, sources) | ||||
|                         if ((maybeDrawerData != null && maybeDrawerData != apiDrawerData) || maybeDrawerData == null) { | ||||
|                             handleDrawerData(apiDrawerData) | ||||
|                         } | ||||
|                     } else { | ||||
|                         val apiDrawerData = DrawerData(tags, null) | ||||
|                         if ((maybeDrawerData != null && maybeDrawerData != apiDrawerData) || maybeDrawerData == null) { | ||||
|                             handleDrawerData(apiDrawerData) | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             CoroutineScope(Dispatchers.IO).launch { | ||||
|                 tags = repository.getTags() | ||||
|                 sourcesApiCall() | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         binding.mainDrawer.itemAdapter.add( | ||||
|             PrimaryDrawerItem().apply { | ||||
|                 nameRes = R.string.drawer_loading | ||||
| @@ -648,16 +394,189 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar | ||||
|             } | ||||
|         ) | ||||
|  | ||||
|         thread { | ||||
|         CoroutineScope(Dispatchers.IO).launch { | ||||
|             val drawerData = DrawerData(repository.getDBTags().map { it.toView() }, | ||||
|                                         repository.getDBSources().map { it.toView() }) | ||||
|             runOnUiThread { | ||||
|                 handleDrawerData(drawerData, loadedFromCache = true) | ||||
|                 drawerApiCalls(drawerData) | ||||
|                 // Only refresh if there is no data in the DB, or if the `UpdateSources` setting is enabled | ||||
|                 if (drawerData.sources?.isEmpty() == true || appSettingsService.isUpdateSourcesEnabled()) { | ||||
|                     drawerApiCalls(drawerData) | ||||
|                 } else { | ||||
|                     handleDrawerData(drawerData, loadedFromCache = true) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun drawerApiCalls(drawerData: DrawerData) { | ||||
|         CoroutineScope(Dispatchers.Main).launch { | ||||
|             val apiDrawerData = DrawerData(repository.getTags(), repository.getSources()) | ||||
|             handleDrawerData(if (drawerData != apiDrawerData) apiDrawerData else drawerData) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun handleDrawerData(drawerData: DrawerData, loadedFromCache: Boolean = false) { | ||||
|         binding.mainDrawer.itemAdapter.clear() | ||||
|  | ||||
|         // Filters title with clear action | ||||
|         secondaryItem(withDivider = false, R.string.drawer_item_filters, DRAWER_ID_FILTERS, R.string.drawer_action_clear) { _,_,_ -> | ||||
|             repository.sourceFilter = null | ||||
|             repository.tagFilter = null | ||||
|             binding.mainDrawer.setSelectionAtPosition(-1) | ||||
|             getElementsAccordingToTab() | ||||
|             fetchOnEmptyList() | ||||
|             false | ||||
|         } | ||||
|  | ||||
|         // Hidden tags | ||||
|         if (drawerData.tags != null && drawerData.tags.isNotEmpty() && appSettingsService.getHiddenTags().isNotEmpty()) { | ||||
|             secondaryItem( | ||||
|                 withDivider = true, | ||||
|                 R.string.drawer_item_hidden_tags, | ||||
|                 DRAWER_ID_HIDDEN_TAGS | ||||
|             ) | ||||
|             handleHiddenTags(drawerData.tags) | ||||
|         } | ||||
|  | ||||
|         // Tags | ||||
|         secondaryItem(withDivider = true, R.string.drawer_item_tags, DRAWER_ID_TAGS) | ||||
|         if (drawerData.tags == null && !loadedFromCache) { | ||||
|             binding.mainDrawer.itemAdapter.add( | ||||
|                 SecondaryDrawerItem() | ||||
|                     .apply { nameRes = R.string.drawer_error_loading_tags; isSelectable = false } | ||||
|             ) | ||||
|         } else { | ||||
|             handleTags(drawerData.tags!!) | ||||
|         } | ||||
|  | ||||
|         // Sources | ||||
|         secondaryItem(withDivider = true, R.string.drawer_item_sources, DRAWER_ID_SOURCES, R.string.drawer_action_edit) { v, _, _ -> | ||||
|             startActivity(Intent(v!!.context, SourcesActivity::class.java)) | ||||
|             false | ||||
|         } | ||||
|         if (drawerData.sources == null && !loadedFromCache) { | ||||
|             binding.mainDrawer.itemAdapter.add( | ||||
|                 SecondaryDrawerItem().apply { | ||||
|                     nameRes = R.string.drawer_error_loading_tags | ||||
|                     isSelectable = false | ||||
|                 } | ||||
|             ) | ||||
|         } else { | ||||
|             handleSources(drawerData.sources!!) | ||||
|         } | ||||
|  | ||||
|         // About action | ||||
|         binding.mainDrawer.itemAdapter.add( | ||||
|             DividerDrawerItem(), | ||||
|             PrimaryDrawerItem().apply { | ||||
|                 nameRes = R.string.action_about | ||||
|                 isSelectable = false | ||||
|                 iconRes = R.drawable.ic_info_outline_white_24dp | ||||
|                 isIconTinted = true | ||||
|                 onDrawerItemClickListener = { _,_,_ -> | ||||
|                     LibsBuilder() | ||||
|                         .withAboutIconShown(true) | ||||
|                         .withAboutVersionShown(true) | ||||
|                         .start(this@HomeActivity) | ||||
|                     false | ||||
|                 } | ||||
|             } | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     private fun secondaryItem(withDivider: Boolean, name: Int, id: Long, badgeId: Int? = null, clickListener: ((v: View?, item: IDrawerItem<*>, position: Int) -> Boolean)? = null) { | ||||
|         if (withDivider) { | ||||
|             binding.mainDrawer.itemAdapter.add(DividerDrawerItem()) | ||||
|         } | ||||
|  | ||||
|         binding.mainDrawer.itemAdapter.add( | ||||
|             SecondaryDrawerItem().apply { | ||||
|                 nameRes = name | ||||
|                 identifier = id | ||||
|                 isSelectable = false | ||||
|                 if (badgeId != null) { | ||||
|                     badgeRes = badgeId | ||||
|                 } | ||||
|                 onDrawerItemClickListener = clickListener | ||||
|             } | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     private fun createDrawerItem(it: SelfossModel.Tag) { | ||||
|         val gd = GradientDrawable() | ||||
|         val gdColor = try { | ||||
|             Color.parseColor(it.color) | ||||
|         } catch (e: IllegalArgumentException) { | ||||
|             appColors.colorPrimary | ||||
|         } | ||||
|         gd.setColor(gdColor) | ||||
|         gd.shape = GradientDrawable.RECTANGLE | ||||
|         gd.setSize(30, 30) | ||||
|         gd.cornerRadius = 30F | ||||
|  | ||||
|         val drawerItem = PrimaryDrawerItem() | ||||
|             .apply { | ||||
|                 nameText = it.tag.getHtmlDecoded() | ||||
|                 identifier = it.tag.longHash() | ||||
|                 iconDrawable = gd | ||||
|                 badgeStyle = BadgeStyle().apply { | ||||
|                     textColor = ColorHolder.fromColor(Color.WHITE) | ||||
|                     color = ColorHolder.fromColor(appColors.colorAccent) | ||||
|                 } | ||||
|                 onDrawerItemClickListener = { _, _, _ -> | ||||
|                     repository.tagFilter = it | ||||
|                     repository.sourceFilter = null | ||||
|                     getElementsAccordingToTab() | ||||
|                     fetchOnEmptyList() | ||||
|                     false | ||||
|                 } | ||||
|             } | ||||
|         if (it.unread > 0) { | ||||
|             drawerItem.badgeText = it.unread.toString() | ||||
|         } | ||||
|  | ||||
|         binding.mainDrawer.itemAdapter.add(drawerItem) | ||||
|     } | ||||
|  | ||||
|     private fun handleTags(tags: List<SelfossModel.Tag>) { | ||||
|         val filteredTags = tags | ||||
|             .filterNot { appSettingsService.getHiddenTags().contains(it.tag) } | ||||
|             .sortedBy { it.tag } | ||||
|         createTagItems(filteredTags) | ||||
|     } | ||||
|  | ||||
|     private fun handleHiddenTags(tags: List<SelfossModel.Tag>) { | ||||
|         val filteredHiddenTags: List<SelfossModel.Tag> = | ||||
|             tags.filter { appSettingsService.getHiddenTags().contains(it.tag) } | ||||
|         createTagItems(filteredHiddenTags) | ||||
|     } | ||||
|  | ||||
|     private fun createTagItems(tags: List<SelfossModel.Tag>) { | ||||
|         tagsBadge = tags.associate { | ||||
|             createDrawerItem(it) | ||||
|  | ||||
|             (it.tag.longHash() to it.unread) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun handleSources(sources: List<SelfossModel.Source>) { | ||||
|         for (source in sources) { | ||||
|             val item = PrimaryDrawerItem().apply { | ||||
|                 nameText = source.title.getHtmlDecoded() | ||||
|                 identifier = source.id.toLong() | ||||
|                 iconUrl = source.getIcon(repository.baseUrl) | ||||
|                 onDrawerItemClickListener = { _,_,_ -> | ||||
|                     repository.sourceFilter = source | ||||
|                     repository.tagFilter = null | ||||
|                     getElementsAccordingToTab() | ||||
|                     fetchOnEmptyList() | ||||
|                     false | ||||
|                 } | ||||
|             } | ||||
|             binding.mainDrawer.itemAdapter.add(item) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun reloadLayoutManager() { | ||||
|         val currentManager = binding.recyclerView.layoutManager | ||||
|         val layoutManager: RecyclerView.LayoutManager | ||||
| @@ -1030,12 +949,5 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar | ||||
|             WorkManager.getInstance(baseContext).enqueueUniquePeriodicWork("selfoss-loading", ExistingPeriodicWorkPolicy.KEEP, backgroundWork) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | ||||
|         super.onActivityResult(requestCode, resultCode, data) | ||||
|         if (requestCode == SETTINGS_ACTIVITY) { | ||||
|             appSettingsService.refreshUserSettings() | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -69,11 +69,13 @@ class SettingsActivity : AppCompatActivity(), | ||||
|     } | ||||
|  | ||||
|     override fun onSupportNavigateUp(): Boolean { | ||||
|         if (supportFragmentManager.popBackStackImmediate()) { | ||||
|         return if (supportFragmentManager.popBackStackImmediate()) { | ||||
|             supportActionBar?.title = getText(R.string.title_activity_settings) | ||||
|             return true | ||||
|             false | ||||
|         } else { | ||||
|             super.onBackPressed() | ||||
|             true | ||||
|         } | ||||
|         return super.onSupportNavigateUp() | ||||
|     } | ||||
|  | ||||
|     override fun onPreferenceStartFragment( | ||||
| @@ -216,11 +218,4 @@ class SettingsActivity : AppCompatActivity(), | ||||
|             setPreferencesFromResource(R.xml.pref_experimental, rootKey) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun onOptionsItemSelected(item: MenuItem): Boolean { | ||||
|         when (item.itemId) { | ||||
|             android.R.id.home -> super.onBackPressed() | ||||
|         } | ||||
|         return super.onOptionsItemSelected(item) | ||||
|     } | ||||
| } | ||||
| @@ -1,43 +0,0 @@ | ||||
| package bou.amine.apps.readerforselfossv2.android.utils | ||||
|  | ||||
| import okhttp3.OkHttpClient | ||||
| import java.security.cert.CertificateException | ||||
| import java.security.cert.X509Certificate | ||||
| import javax.net.ssl.SSLContext | ||||
| import javax.net.ssl.TrustManager | ||||
| import javax.net.ssl.X509TrustManager | ||||
|  | ||||
| fun getUnsafeHttpClient(): OkHttpClient.Builder = | ||||
|     try { | ||||
|         // Create a trust manager that does not validate certificate chains | ||||
|         val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager { | ||||
|             override fun getAcceptedIssuers(): Array<X509Certificate> = | ||||
|                 arrayOf() | ||||
|  | ||||
|             @Throws(CertificateException::class) | ||||
|             override fun checkClientTrusted( | ||||
|                 chain: Array<java.security.cert.X509Certificate>, | ||||
|                 authType: String | ||||
|             ) { | ||||
|             } | ||||
|  | ||||
|             @Throws(CertificateException::class) | ||||
|             override fun checkServerTrusted( | ||||
|                 chain: Array<java.security.cert.X509Certificate>, | ||||
|                 authType: String | ||||
|             ) { | ||||
|             } | ||||
|         }) | ||||
|  | ||||
|         // Install the all-trusting trust manager | ||||
|         val sslContext = SSLContext.getInstance("SSL") | ||||
|         sslContext.init(null, trustAllCerts, java.security.SecureRandom()) | ||||
|  | ||||
|         val sslSocketFactory = sslContext.socketFactory | ||||
|  | ||||
|         OkHttpClient.Builder() | ||||
|             .sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager) | ||||
|             .hostnameVerifier { _, _ -> true } | ||||
|     } catch (e: Exception) { | ||||
|         throw RuntimeException(e) | ||||
|     } | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 406 B | 
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">L\'alçada de les targetes serà fixa</string> | ||||
|     <string name="source_code">Codi font</string> | ||||
|     <string name="drawer_error_loading_tags">S\'ha produït un error en carregar les etiquetes</string> | ||||
|     <string name="drawer_error_loading_sources">S\'ha produït un error en carregar les fonts</string> | ||||
|     <string name="drawer_item_filters">Filtres</string> | ||||
|     <string name="drawer_action_clear">Esborra</string> | ||||
|     <string name="drawer_item_tags">Etiquetes</string> | ||||
|     <string name="drawer_item_sources">Fonts</string> | ||||
|     <string name="drawer_action_edit">Edita</string> | ||||
|     <string name="no_tags_loaded">No s\'ha carregat cap etiqueta</string> | ||||
|     <string name="no_sources_loaded">No s\'ha carregat cap font</string> | ||||
|     <string name="drawer_loading">S\'està carregant…</string> | ||||
|     <string name="menu_home_search">Cerca</string> | ||||
|     <string name="can_delete_source">No es pot suprimir la font</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">API de Selfoss</string> | ||||
|     <string name="pref_api_items_number_title">Nombre d\'elements carregats</string> | ||||
|     <string name="pref_hidden_tags">Etiquetes ocultes</string> | ||||
|     <string name="display_header_drawer_summary">Mostra una capçalera amb la instància URL de Selfoss al panell lateral.</string> | ||||
|     <string name="display_header_drawer_title">Capçalera de menú</string> | ||||
|     <string name="pref_general_infinite_loading_title">Carrega articles en desplaçar</string> | ||||
|     <string name="translation">Traducció</string> | ||||
|     <string name="cant_open_invalid_url">L\'element URL no és vàlid. Estic intentant solucionar aquest problema perquè l\'aplicació no falli.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Kartenhöhe ist fix</string> | ||||
|     <string name="source_code">Quellcode</string> | ||||
|     <string name="drawer_error_loading_tags">Fehler beim Laden der Tags…</string> | ||||
|     <string name="drawer_error_loading_sources">Fehler beim Laden der Quellen…</string> | ||||
|     <string name="drawer_item_filters">Filter</string> | ||||
|     <string name="drawer_action_clear">leeren</string> | ||||
|     <string name="drawer_item_tags">Tags</string> | ||||
|     <string name="drawer_item_sources">Quellen</string> | ||||
|     <string name="drawer_action_edit">bearbeiten</string> | ||||
|     <string name="no_tags_loaded">No tags loaded</string> | ||||
|     <string name="no_sources_loaded">Keine Quellen geladen</string> | ||||
|     <string name="drawer_loading">Lade…</string> | ||||
|     <string name="menu_home_search">Suche</string> | ||||
|     <string name="can_delete_source">Can\'t delete the source…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">selfoss API</string> | ||||
|     <string name="pref_api_items_number_title">Loaded items number</string> | ||||
|     <string name="pref_hidden_tags">Hidden Tags</string> | ||||
|     <string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string> | ||||
|     <string name="display_header_drawer_title">Account header</string> | ||||
|     <string name="pref_general_infinite_loading_title">Load more articles on scroll</string> | ||||
|     <string name="translation">Übersetzung</string> | ||||
|     <string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Se fijará la altura de la tarjeta</string> | ||||
|     <string name="source_code">Código fuente</string> | ||||
|     <string name="drawer_error_loading_tags">Error al cargar etiquetas…</string> | ||||
|     <string name="drawer_error_loading_sources">Error al cargar fuentes…</string> | ||||
|     <string name="drawer_item_filters">Filtros</string> | ||||
|     <string name="drawer_action_clear">limpiar</string> | ||||
|     <string name="drawer_item_tags">Etiquetas</string> | ||||
|     <string name="drawer_item_sources">Fuentes</string> | ||||
|     <string name="drawer_action_edit">editar</string> | ||||
|     <string name="no_tags_loaded">No hay etiquetas cargadas</string> | ||||
|     <string name="no_sources_loaded">No hay fuentes cargadas</string> | ||||
|     <string name="drawer_loading">Cargando…</string> | ||||
|     <string name="menu_home_search">Buscar</string> | ||||
|     <string name="can_delete_source">No se puede eliminar la fuente…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Api de Selfoss</string> | ||||
|     <string name="pref_api_items_number_title">Número de artículos cargados</string> | ||||
|     <string name="pref_hidden_tags">Etiquetas ocultas</string> | ||||
|     <string name="display_header_drawer_summary">Mostrar una cabecera con la url de instancia de selfoss en el cajón lateral.</string> | ||||
|     <string name="display_header_drawer_title">Cabecera de cuenta</string> | ||||
|     <string name="pref_general_infinite_loading_title">Cargar más artículos en desplazamiento</string> | ||||
|     <string name="translation">Traducción</string> | ||||
|     <string name="cant_open_invalid_url">La url del elemento no es válida. Estoy buscando resolver este problema para que la aplicación no colapse.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Card height will be fixed</string> | ||||
|     <string name="source_code">Source code</string> | ||||
|     <string name="drawer_error_loading_tags">Error loading tags…</string> | ||||
|     <string name="drawer_error_loading_sources">Error loading sources…</string> | ||||
|     <string name="drawer_item_filters">Filters</string> | ||||
|     <string name="drawer_action_clear">clear</string> | ||||
|     <string name="drawer_item_tags">Tags</string> | ||||
|     <string name="drawer_item_sources">Sources</string> | ||||
|     <string name="drawer_action_edit">edit</string> | ||||
|     <string name="no_tags_loaded">No tags loaded</string> | ||||
|     <string name="no_sources_loaded">No sources loaded</string> | ||||
|     <string name="drawer_loading">Loading …</string> | ||||
|     <string name="menu_home_search">Search</string> | ||||
|     <string name="can_delete_source">Can\'t delete the source…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Selfoss Api</string> | ||||
|     <string name="pref_api_items_number_title">Loaded items number</string> | ||||
|     <string name="pref_hidden_tags">Hidden Tags</string> | ||||
|     <string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string> | ||||
|     <string name="display_header_drawer_title">Account header</string> | ||||
|     <string name="pref_general_infinite_loading_title">Load more articles on scroll</string> | ||||
|     <string name="translation">Translation</string> | ||||
|     <string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">La taille de la carte sera fixe</string> | ||||
|     <string name="source_code">Code source</string> | ||||
|     <string name="drawer_error_loading_tags">Erreur lors du chargement des tags…</string> | ||||
|     <string name="drawer_error_loading_sources">Erreur lors du chargement des sources…</string> | ||||
|     <string name="drawer_item_filters">Filtres</string> | ||||
|     <string name="drawer_action_clear">raz</string> | ||||
|     <string name="drawer_item_tags">Tags</string> | ||||
|     <string name="drawer_item_sources">Sources</string> | ||||
|     <string name="drawer_action_edit">éditer</string> | ||||
|     <string name="no_tags_loaded">Pas de tags chargés</string> | ||||
|     <string name="no_sources_loaded">Pas de sources chargés</string> | ||||
|     <string name="drawer_loading">Chargement …</string> | ||||
|     <string name="menu_home_search">Rechercher</string> | ||||
|     <string name="can_delete_source">Impossible de supprimer la source…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Api Selfoss</string> | ||||
|     <string name="pref_api_items_number_title">Nombre d\'articles chargés</string> | ||||
|     <string name="pref_hidden_tags">Tags Cachés</string> | ||||
|     <string name="display_header_drawer_summary">Afficher une entête avec l\'url de votre instance de Selfoss en haut du drawer lateral.</string> | ||||
|     <string name="display_header_drawer_title">Entête de compte</string> | ||||
|     <string name="pref_general_infinite_loading_title">Charger plus d\'articles au scroll</string> | ||||
|     <string name="translation">Traduction</string> | ||||
|     <string name="cant_open_invalid_url">L’url de l’élément n’est pas valide. En attendant la résolution du problème, le lien ne s\'ouvrira pas.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">A altura das tarxetas será fixa</string> | ||||
|     <string name="source_code">Código fonte</string> | ||||
|     <string name="drawer_error_loading_tags">Produciuse un erro ao cargar as etiquetas…</string> | ||||
|     <string name="drawer_error_loading_sources">Produciuse un erro ao cargar as fontes…</string> | ||||
|     <string name="drawer_item_filters">Filtros</string> | ||||
|     <string name="drawer_action_clear">limpar</string> | ||||
|     <string name="drawer_item_tags">Etiquetas</string> | ||||
|     <string name="drawer_item_sources">Fontes</string> | ||||
|     <string name="drawer_action_edit">editar</string> | ||||
|     <string name="no_tags_loaded">Non se cargou ningunha etiqueta</string> | ||||
|     <string name="no_sources_loaded">Non se cargou ningunha fonte</string> | ||||
|     <string name="drawer_loading">Cargando…</string> | ||||
|     <string name="menu_home_search">Procurar</string> | ||||
|     <string name="can_delete_source">Non se puido eliminar a fonte…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">API de Selfoss</string> | ||||
|     <string name="pref_api_items_number_title">Número de elementos cargados</string> | ||||
|     <string name="pref_hidden_tags">Etiquetas ocultas</string> | ||||
|     <string name="display_header_drawer_summary">Amosar unha cabeceira coa URL da instancia de Selfoss no panel lateral.</string> | ||||
|     <string name="display_header_drawer_title">Cabeceira da conta</string> | ||||
|     <string name="pref_general_infinite_loading_title">Cargar máis artigos ao desprazarse</string> | ||||
|     <string name="translation">Traducción</string> | ||||
|     <string name="cant_open_invalid_url">A URL do elemento non é válida. Estou tratando de solucionar isto pra que a aplicación non falle.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Ukuran kartu akan tetap</string> | ||||
|     <string name="source_code">Kode sumber</string> | ||||
|     <string name="drawer_error_loading_tags">Kesalahan saat memuat tag…</string> | ||||
|     <string name="drawer_error_loading_sources">Kesalahan saat memuat sumber…</string> | ||||
|     <string name="drawer_item_filters">Filter</string> | ||||
|     <string name="drawer_action_clear">kosongkan</string> | ||||
|     <string name="drawer_item_tags">Tag</string> | ||||
|     <string name="drawer_item_sources">Sumber</string> | ||||
|     <string name="drawer_action_edit">suntung</string> | ||||
|     <string name="no_tags_loaded">Tidak ada tag yang dimuat</string> | ||||
|     <string name="no_sources_loaded">Tak ada sumber yang dimuat</string> | ||||
|     <string name="drawer_loading">Memuat …</string> | ||||
|     <string name="menu_home_search">Cari</string> | ||||
|     <string name="can_delete_source">Tidak dapat menghapus sumber…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Selfoss Api</string> | ||||
|     <string name="pref_api_items_number_title">Item nomor dimuat</string> | ||||
|     <string name="pref_hidden_tags">Hidden Tags</string> | ||||
|     <string name="display_header_drawer_summary">Kop dengan alamat link Selfoss ditampilkan di laci lateral.</string> | ||||
|     <string name="display_header_drawer_title">Kop akun</string> | ||||
|     <string name="pref_general_infinite_loading_title">Muat lebih banyak artikel saat membalik halaman</string> | ||||
|     <string name="translation">Terjemahan</string> | ||||
|     <string name="cant_open_invalid_url">Alamat tautan proyek tidak valid. Saya mencoba memecahkan masalah ini untuk menghindari aplikasi berhenti.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Card height will be fixed</string> | ||||
|     <string name="source_code">Codice sorgente</string> | ||||
|     <string name="drawer_error_loading_tags">Errore nel caricamento dei tag…</string> | ||||
|     <string name="drawer_error_loading_sources">Errore nel caricamento delle fonti…</string> | ||||
|     <string name="drawer_item_filters">Filtri</string> | ||||
|     <string name="drawer_action_clear">cancella</string> | ||||
|     <string name="drawer_item_tags">Tags</string> | ||||
|     <string name="drawer_item_sources">Fonti</string> | ||||
|     <string name="drawer_action_edit">modifica</string> | ||||
|     <string name="no_tags_loaded">Nessun tag caricato</string> | ||||
|     <string name="no_sources_loaded">No sources loaded</string> | ||||
|     <string name="drawer_loading">Caricamento…</string> | ||||
|     <string name="menu_home_search">Cerca</string> | ||||
|     <string name="can_delete_source">Non è possibile eliminare la fonte…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Api di Selfoss</string> | ||||
|     <string name="pref_api_items_number_title">Numero di elementi caricati</string> | ||||
|     <string name="pref_hidden_tags">Tag nascosti</string> | ||||
|     <string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string> | ||||
|     <string name="display_header_drawer_title">Account header</string> | ||||
|     <string name="pref_general_infinite_loading_title">Load more articles on scroll</string> | ||||
|     <string name="translation">Traduzioni</string> | ||||
|     <string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Card height will be fixed</string> | ||||
|     <string name="source_code">Source code</string> | ||||
|     <string name="drawer_error_loading_tags">Error loading tags…</string> | ||||
|     <string name="drawer_error_loading_sources">Error loading sources…</string> | ||||
|     <string name="drawer_item_filters">Filters</string> | ||||
|     <string name="drawer_action_clear">clear</string> | ||||
|     <string name="drawer_item_tags">Tags</string> | ||||
|     <string name="drawer_item_sources">Sources</string> | ||||
|     <string name="drawer_action_edit">edit</string> | ||||
|     <string name="no_tags_loaded">No tags loaded</string> | ||||
|     <string name="no_sources_loaded">No sources loaded</string> | ||||
|     <string name="drawer_loading">Loading …</string> | ||||
|     <string name="menu_home_search">Search</string> | ||||
|     <string name="can_delete_source">Can\'t delete the source…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Selfoss Api</string> | ||||
|     <string name="pref_api_items_number_title">Loaded items number</string> | ||||
|     <string name="pref_hidden_tags">Hidden Tags</string> | ||||
|     <string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string> | ||||
|     <string name="display_header_drawer_title">Account header</string> | ||||
|     <string name="pref_general_infinite_loading_title">Load more articles on scroll</string> | ||||
|     <string name="translation">Translation</string> | ||||
|     <string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Vaste hoogte</string> | ||||
|     <string name="source_code">Broncode</string> | ||||
|     <string name="drawer_error_loading_tags">Fout bij het laden van tags…</string> | ||||
|     <string name="drawer_error_loading_sources">Fout bij laden van bronnen…</string> | ||||
|     <string name="drawer_item_filters">Filters</string> | ||||
|     <string name="drawer_action_clear">wissen</string> | ||||
|     <string name="drawer_item_tags">Tags</string> | ||||
|     <string name="drawer_item_sources">Bronnen</string> | ||||
|     <string name="drawer_action_edit">bewerken</string> | ||||
|     <string name="no_tags_loaded">Geen tags geladen</string> | ||||
|     <string name="no_sources_loaded">Geen bronnen geladen</string> | ||||
|     <string name="drawer_loading">Bezig met laden …</string> | ||||
|     <string name="menu_home_search">Zoeken</string> | ||||
|     <string name="can_delete_source">Kan de bron niet verwijderen…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Selfoss Api</string> | ||||
|     <string name="pref_api_items_number_title">Geladen items nummer</string> | ||||
|     <string name="pref_hidden_tags">Hidden Tags</string> | ||||
|     <string name="display_header_drawer_summary">Laat een koptekst weergeven met de url van de selfoss instantie in de zijlade.</string> | ||||
|     <string name="display_header_drawer_title">Account titel</string> | ||||
|     <string name="pref_general_infinite_loading_title">Laad meer artikelen door te bladeren</string> | ||||
|     <string name="translation">Vertaling</string> | ||||
|     <string name="cant_open_invalid_url">De URL is ongeldig. Ik probeer dit probleem op te lossen, zodat de toepassing niet wordt afgesloten.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Cards com altura de tamanho fixo</string> | ||||
|     <string name="source_code">Código fonte</string> | ||||
|     <string name="drawer_error_loading_tags">Erro ao carregar as tags…</string> | ||||
|     <string name="drawer_error_loading_sources">Erro ao carregar as fontes…</string> | ||||
|     <string name="drawer_item_filters">Filtros</string> | ||||
|     <string name="drawer_action_clear">limpar</string> | ||||
|     <string name="drawer_item_tags">Tags</string> | ||||
|     <string name="drawer_item_sources">Fontes</string> | ||||
|     <string name="drawer_action_edit">editar</string> | ||||
|     <string name="no_tags_loaded">Nenhuma tag carregada</string> | ||||
|     <string name="no_sources_loaded">Nenhuma fonte carregada</string> | ||||
|     <string name="drawer_loading">Carregando …</string> | ||||
|     <string name="menu_home_search">Procurar</string> | ||||
|     <string name="can_delete_source">Não foi possível apagar a fonte…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Selfoss Api</string> | ||||
|     <string name="pref_api_items_number_title">Quantidade de itens carregados</string> | ||||
|     <string name="pref_hidden_tags">Hidden Tags</string> | ||||
|     <string name="display_header_drawer_summary">Exibir um cabeçalho com o URL da instância do Selfoss na barra lateral.</string> | ||||
|     <string name="display_header_drawer_title">Cabeçalho da conta</string> | ||||
|     <string name="pref_general_infinite_loading_title">Carregar mais artigos ao realizar o scroll</string> | ||||
|     <string name="translation">Traduções</string> | ||||
|     <string name="cant_open_invalid_url">A url está inválida. Estou tentando resolver esse problema para que o aplicativo não encerre.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Altura do cartão será corrigida</string> | ||||
|     <string name="source_code">Código fonte</string> | ||||
|     <string name="drawer_error_loading_tags">Erro ao carregar etiquetas…</string> | ||||
|     <string name="drawer_error_loading_sources">Erro ao carregar fontes…</string> | ||||
|     <string name="drawer_item_filters">Filtros</string> | ||||
|     <string name="drawer_action_clear">limpar</string> | ||||
|     <string name="drawer_item_tags">Etiquetas</string> | ||||
|     <string name="drawer_item_sources">Fontes</string> | ||||
|     <string name="drawer_action_edit">editar</string> | ||||
|     <string name="no_tags_loaded">Não tags carregado</string> | ||||
|     <string name="no_sources_loaded">Não há fontes carregadas</string> | ||||
|     <string name="drawer_loading">A carregar…</string> | ||||
|     <string name="menu_home_search">Buscar</string> | ||||
|     <string name="can_delete_source">Não é possível excluir a fonte…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Api de Selfoss</string> | ||||
|     <string name="pref_api_items_number_title">Número de itens carregados</string> | ||||
|     <string name="pref_hidden_tags">Hidden Tags</string> | ||||
|     <string name="display_header_drawer_summary">Exibir um cabeçalho com o url de instância de selfoss na gaveta lateral.</string> | ||||
|     <string name="display_header_drawer_title">Cabeçalho de conta</string> | ||||
|     <string name="pref_general_infinite_loading_title">Carregar mais artigos no pergaminho</string> | ||||
|     <string name="translation">Tradução</string> | ||||
|     <string name="cant_open_invalid_url">A url do item é inválido. Eu estou olhando para resolver esta questão, para que o app não vai falhar.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Card height will be fixed</string> | ||||
|     <string name="source_code">Source code</string> | ||||
|     <string name="drawer_error_loading_tags">Error loading tags…</string> | ||||
|     <string name="drawer_error_loading_sources">Error loading sources…</string> | ||||
|     <string name="drawer_item_filters">Filters</string> | ||||
|     <string name="drawer_action_clear">clear</string> | ||||
|     <string name="drawer_item_tags">Tags</string> | ||||
|     <string name="drawer_item_sources">Sources</string> | ||||
|     <string name="drawer_action_edit">edit</string> | ||||
|     <string name="no_tags_loaded">No tags loaded</string> | ||||
|     <string name="no_sources_loaded">No sources loaded</string> | ||||
|     <string name="drawer_loading">Loading …</string> | ||||
|     <string name="menu_home_search">Search</string> | ||||
|     <string name="can_delete_source">Can\'t delete the source…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Selfoss Api</string> | ||||
|     <string name="pref_api_items_number_title">Loaded items number</string> | ||||
|     <string name="pref_hidden_tags">Hidden Tags</string> | ||||
|     <string name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string> | ||||
|     <string name="display_header_drawer_title">Account header</string> | ||||
|     <string name="pref_general_infinite_loading_title">Load more articles on scroll</string> | ||||
|     <string name="translation">Translation</string> | ||||
|     <string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Kart yüksekliği sabit olacak</string> | ||||
|     <string name="source_code">Kaynak kodu</string> | ||||
|     <string name="drawer_error_loading_tags">Etiketler yükleme hatası…</string> | ||||
|     <string name="drawer_error_loading_sources">Kaynaklar yüklenirken hata oluştu…</string> | ||||
|     <string name="drawer_item_filters">Filtreler</string> | ||||
|     <string name="drawer_action_clear">temizle</string> | ||||
|     <string name="drawer_item_tags">Etiketler</string> | ||||
|     <string name="drawer_item_sources">Kaynaklar</string> | ||||
|     <string name="drawer_action_edit">düzenle</string> | ||||
|     <string name="no_tags_loaded">Yüklenen görüntü yok</string> | ||||
|     <string name="no_sources_loaded">Yüklenen kaynak yok</string> | ||||
|     <string name="drawer_loading">Yükleniyor…</string> | ||||
|     <string name="menu_home_search">Ara</string> | ||||
|     <string name="can_delete_source">Kaynak silinemiyor…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Selfoss Uygulaması</string> | ||||
|     <string name="pref_api_items_number_title">Yüklenen öğe numarası</string> | ||||
|     <string name="pref_hidden_tags">Hidden Tags</string> | ||||
|     <string name="display_header_drawer_summary">Selfoss örneği url\'li bir üstbilgi, yan çekmece üzerine gösterin.</string> | ||||
|     <string name="display_header_drawer_title">Hesap başlığı</string> | ||||
|     <string name="pref_general_infinite_loading_title">Kaydırma üzerine daha fazla makale yükleyin</string> | ||||
|     <string name="translation">Çeviri</string> | ||||
|     <string name="cant_open_invalid_url">Öğe url geçersiz. Uygulama çökmeyeceği için bu sorunu çözmeye çalışıyorum.</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">卡片高度将被固定</string> | ||||
|     <string name="source_code">源代码</string> | ||||
|     <string name="drawer_error_loading_tags">加载标记时出错..。</string> | ||||
|     <string name="drawer_error_loading_sources">加载源时出错..。</string> | ||||
|     <string name="drawer_item_filters">搜索条件</string> | ||||
|     <string name="drawer_action_clear">清空</string> | ||||
|     <string name="drawer_item_tags">标签</string> | ||||
|     <string name="drawer_item_sources">来源</string> | ||||
|     <string name="drawer_action_edit">编辑</string> | ||||
|     <string name="no_tags_loaded">未加载标签</string> | ||||
|     <string name="no_sources_loaded">未加载数据源</string> | ||||
|     <string name="drawer_loading">正在载入…</string> | ||||
|     <string name="menu_home_search">搜索</string> | ||||
|     <string name="can_delete_source">无法删除数据源…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">塞尔福斯 Api</string> | ||||
|     <string name="pref_api_items_number_title">已加载项目编号</string> | ||||
|     <string name="pref_hidden_tags">隐藏标签</string> | ||||
|     <string name="display_header_drawer_summary">在侧边栏中显示带有 Selfoss 链接地址的页眉。</string> | ||||
|     <string name="display_header_drawer_title">帐户页眉</string> | ||||
|     <string name="pref_general_infinite_loading_title">翻页时载入更多文章</string> | ||||
|     <string name="translation">翻译</string> | ||||
|     <string name="cant_open_invalid_url">项目链接地址无效。我正在设法解决这个问题,以避免应用程序崩溃。</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">卡片高度将被固定</string> | ||||
|     <string name="source_code">源代码</string> | ||||
|     <string name="drawer_error_loading_tags">加载标记时出错..。</string> | ||||
|     <string name="drawer_error_loading_sources">加载源时出错..。</string> | ||||
|     <string name="drawer_item_filters">搜索条件</string> | ||||
|     <string name="drawer_action_clear">清空</string> | ||||
|     <string name="drawer_item_tags">标签</string> | ||||
|     <string name="drawer_item_sources">来源</string> | ||||
|     <string name="drawer_action_edit">编辑</string> | ||||
|     <string name="no_tags_loaded">未加载标签</string> | ||||
|     <string name="no_sources_loaded">未加载数据源</string> | ||||
|     <string name="drawer_loading">正在载入…</string> | ||||
|     <string name="menu_home_search">搜索</string> | ||||
|     <string name="can_delete_source">无法删除数据源…</string> | ||||
| @@ -84,8 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">塞尔福斯 Api</string> | ||||
|     <string name="pref_api_items_number_title">已加载项目编号</string> | ||||
|     <string name="pref_hidden_tags">Hidden Tags</string> | ||||
|     <string name="display_header_drawer_summary">在侧边栏中显示带有 Selfoss 链接地址的页眉。</string> | ||||
|     <string name="display_header_drawer_title">帐户页眉</string> | ||||
|     <string name="pref_general_infinite_loading_title">翻页时载入更多文章</string> | ||||
|     <string name="translation">翻译</string> | ||||
|     <string name="cant_open_invalid_url">项目链接地址无效。我正在设法解决这个问题,以避免应用程序崩溃。</string> | ||||
|   | ||||
| @@ -66,14 +66,11 @@ | ||||
|     <string name="card_height_off">Card height will be fixed</string> | ||||
|     <string name="source_code">Source code</string> | ||||
|     <string name="drawer_error_loading_tags">Error loading tags…</string> | ||||
|     <string name="drawer_error_loading_sources">Error loading sources…</string> | ||||
|     <string name="drawer_item_filters">Filters</string> | ||||
|     <string name="drawer_action_clear">clear</string> | ||||
|     <string name="drawer_item_tags">Tags</string> | ||||
|     <string name="drawer_item_sources">Sources</string> | ||||
|     <string name="drawer_action_edit">edit</string> | ||||
|     <string name="no_tags_loaded">No tags loaded</string> | ||||
|     <string name="no_sources_loaded">No sources loaded</string> | ||||
|     <string name="drawer_loading">Loading …</string> | ||||
|     <string name="menu_home_search">Search</string> | ||||
|     <string name="can_delete_source">Can\'t delete the source…</string> | ||||
| @@ -84,9 +81,6 @@ | ||||
|     <string name="pref_selfoss_category">Selfoss Api</string> | ||||
|     <string name="pref_api_items_number_title">Loaded items number</string> | ||||
|     <string name="pref_hidden_tags">Hidden Tags</string> | ||||
|     <string | ||||
|         name="display_header_drawer_summary">Display a header with the selfoss instance url on the lateral drawer.</string> | ||||
|     <string name="display_header_drawer_title">Account header</string> | ||||
|     <string name="pref_general_infinite_loading_title">Load more articles on scroll</string> | ||||
|     <string name="translation">Translation</string> | ||||
|     <string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string> | ||||
|   | ||||
							
								
								
									
										17
									
								
								androidApp/src/main/res/xml/data_extraction_rules.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								androidApp/src/main/res/xml/data_extraction_rules.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <data-extraction-rules> | ||||
|     <cloud-backup> | ||||
|         <exclude domain="root" /> | ||||
|         <exclude domain="file" /> | ||||
|         <exclude domain="database" /> | ||||
|         <exclude domain="sharedpref" /> | ||||
|         <exclude domain="external" /> | ||||
|     </cloud-backup> | ||||
|     <device-transfer> | ||||
|         <exclude domain="root" /> | ||||
|         <exclude domain="file" /> | ||||
|         <exclude domain="database" /> | ||||
|         <exclude domain="sharedpref" /> | ||||
|         <exclude domain="external" /> | ||||
|     </device-transfer> | ||||
| </data-extraction-rules> | ||||
| @@ -60,12 +60,6 @@ | ||||
|         android:title="@string/pref_general_category_displaying"> | ||||
|  | ||||
|     </PreferenceCategory> | ||||
|     <SwitchPreference | ||||
|         android:defaultValue="false" | ||||
|         android:key="account_header_displaying" | ||||
|         android:summary="@string/display_header_drawer_summary" | ||||
|         android:title="@string/display_header_drawer_title" | ||||
|         app:iconSpaceReserved="false"/> | ||||
|     <SwitchPreference | ||||
|         android:defaultValue="false" | ||||
|         android:key="card_view_active" | ||||
|   | ||||
| @@ -1,11 +0,0 @@ | ||||
| #!/bin/bash | ||||
| # You can pass --force as first parameter to force push and tag creation. | ||||
|  | ||||
| echo "Creating tag $@" | ||||
|  | ||||
| TAG="v$@" | ||||
| git tag ${TAG} | ||||
|  | ||||
| echo "Pushing tag" | ||||
|  | ||||
| git push origin ${TAG} | ||||
| @@ -2,7 +2,7 @@ | ||||
| 
 | ||||
| git fetch --tags -p | ||||
| 
 | ||||
| BASE_VERSION="1.7" | ||||
| BASE_VERSION="1" | ||||
| LAST_TAG=$(git tag -l | sort -V | tail -1) | ||||
| 
 | ||||
| INITIAL_VERSION="${BASE_VERSION//./}$(date '+%y%m%j')" | ||||
| @@ -21,11 +21,11 @@ VERSION="${INITIAL_VERSION}${TODAYS_VERSION}" | ||||
| 
 | ||||
| PARAMS_EXCEPT_PUBLISH=$(echo $1 | sed 's/\-\-publish//') | ||||
| 
 | ||||
| ./version.sh ${VERSION} ${PARAMS_EXCEPT_PUBLISH} | ||||
| ./version.sh ${VERSION} ${PARAMS_EXCEPT_PUBLISH} $@ | ||||
| 
 | ||||
| if [[ "$@" == *'--publish'* ]] | ||||
| then | ||||
|     ./publish-version.sh ${VERSION} | ||||
|     ./publish-version.sh ${VERSION} $@ | ||||
| else | ||||
|     echo "Did not publish. If you wanted to do so, call the script with \"--publish\" or \"--publish-local\"." | ||||
| fi | ||||
| @@ -1,3 +1 @@ | ||||
| A new RSS reader for <a href="http://selfoss.aditu.de/">selfoss</a>. | ||||
|  | ||||
| It connects to your selfoss instance (works only with selfoss, and can't work without it), and you'll be able to read and manage all your RSS feeds. | ||||
|   | ||||
							
								
								
									
										15
									
								
								publish-version.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								publish-version.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # NOTE: This is copy/pasted in jenkins | ||||
|  | ||||
| rm -f version.txt | ||||
| printf "versionName=$1-github\nversionCode=$1" >> version.txt | ||||
|  | ||||
| if [[ "$@" == *'--from-ci'* ]] | ||||
| then | ||||
|         echo "File created. HANDLE IN CI" | ||||
| else | ||||
|   # You'll need to change server as your server and define a VERSION_PATH. | ||||
|   scp version.txt server:$VERSION_PATH | ||||
|   rm version.txt | ||||
| fi | ||||
| @@ -137,7 +137,11 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap | ||||
|  | ||||
|     suspend fun getTags(): List<SelfossModel.Tag>? { | ||||
|         return if (isNetworkAvailable()) { | ||||
|             api.tags() | ||||
|             val apiTags = api.tags() | ||||
|             if (apiTags != null && (appSettingsService.isItemCachingEnabled() || !appSettingsService.isUpdateSourcesEnabled())) { | ||||
|                 resetDBTagsWithData(apiTags) | ||||
|             } | ||||
|             apiTags | ||||
|         } else { | ||||
|             getDBTags().map { it.toView() } | ||||
|         } | ||||
| @@ -152,9 +156,12 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap | ||||
|     } | ||||
|  | ||||
|     suspend fun getSources(): ArrayList<SelfossModel.Source>? { | ||||
|  | ||||
|         return if (isNetworkAvailable()) { | ||||
|             api.sources() | ||||
|             val apiSources = api.sources() | ||||
|             if (apiSources != null && (appSettingsService.isItemCachingEnabled() || !appSettingsService.isUpdateSourcesEnabled())) { | ||||
|                 resetDBSourcesWithData(apiSources) | ||||
|             } | ||||
|             apiSources | ||||
|         } else { | ||||
|             ArrayList(getDBSources().map { it.toView() }) | ||||
|         } | ||||
|   | ||||
| @@ -25,7 +25,6 @@ class AppSettingsService { | ||||
|     private var _periodicRefresh: Boolean? = null | ||||
|     private var _refreshWhenChargingOnly: Boolean? = null | ||||
|     private var _infiniteLoading: Boolean? = null | ||||
|     private var _displayAccountHeader: Boolean? = null | ||||
|     private var _notifyNewItems: Boolean? = null | ||||
|     private var _itemsNumber: Int? = null | ||||
|     private var _apiTimeout: Long? = null | ||||
| @@ -34,9 +33,9 @@ class AppSettingsService { | ||||
|     private var _markOnScroll: Boolean? = null | ||||
|     private var _activeAlignment: Int? = null | ||||
|  | ||||
|     private var _fontSize: Int? = null // settings.getString("reader_font_size", "16").toInt() | ||||
|     private var _staticBar: Boolean? = null // settings.getBoolean("reader_static_bar", false) | ||||
|     private var _font: String = "" // settings.getString("reader_font", "") | ||||
|     private var _fontSize: Int? = null | ||||
|     private var _staticBar: Boolean? = null | ||||
|     private var _font: String = "" | ||||
|  | ||||
|  | ||||
|     init { | ||||
| @@ -247,17 +246,6 @@ class AppSettingsService { | ||||
|         return _infiniteLoading == true | ||||
|     } | ||||
|  | ||||
|     private fun refreshDisplayAccountHeaderEnabled() { | ||||
|         _displayAccountHeader = settings.getBoolean("account_header_displaying", false) | ||||
|     } | ||||
|  | ||||
|     fun isDisplayAccountHeaderEnabled(): Boolean { | ||||
|         if (_displayAccountHeader != null) { | ||||
|             refreshDisplayAccountHeaderEnabled() | ||||
|         } | ||||
|         return _displayAccountHeader == true | ||||
|     } | ||||
|  | ||||
|     private fun refreshItemCachingEnabled() { | ||||
|         _itemsCaching = settings.getBoolean("items_caching", false) | ||||
|     } | ||||
| @@ -364,7 +352,6 @@ class AppSettingsService { | ||||
|         refreshRefreshMinutes() | ||||
|         refreshHiddenTags() | ||||
|         refreshInfiniteLoadingEnabled() | ||||
|         refreshDisplayAccountHeaderEnabled() | ||||
|         refreshItemCachingEnabled() | ||||
|         refreshNotifyNewItemsEnabled() | ||||
|         refreshMarkOnScrollEnabled() | ||||
|   | ||||
							
								
								
									
										14
									
								
								version.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								version.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| echo "Creating tag $1" | ||||
|  | ||||
| TAG="v$1" | ||||
| git tag -a ${TAG} -m ${TAG} | ||||
|  | ||||
| if [[ "$@" == *'--from-ci'* ]] | ||||
| then | ||||
|         echo "Tag created. HANDLE IN CI" | ||||
| else | ||||
|   echo "Pushing tag" | ||||
|   git push origin ${TAG} | ||||
| fi | ||||
		Reference in New Issue
	
	Block a user