Merge pull request #5098 from k9mail/changelog_fragment

Add fragment to show the changelog
This commit is contained in:
cketti 2021-01-22 13:31:50 +01:00 committed by GitHub
commit ac95fe9e33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 308 additions and 25 deletions

View file

@ -32,7 +32,7 @@ dependencies {
implementation "androidx.localbroadcastmanager:localbroadcastmanager:${versions.androidxLocalBroadcastManager}"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "com.google.android.material:material:${versions.materialComponents}"
implementation "de.cketti.library.changelog:ckchangelog:1.2.1"
implementation "de.cketti.library.changelog:ckchangelog-core:2.0.0-beta01"
implementation "com.splitwise:tokenautocomplete:4.0.0-beta01"
implementation "de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0"
implementation 'com.mikepenz:materialdrawer:7.0.0'

View file

@ -6,6 +6,7 @@ import com.fsck.k9.autodiscovery.providersxml.autodiscoveryProvidersXmlModule
import com.fsck.k9.contacts.contactsModule
import com.fsck.k9.fragment.fragmentModule
import com.fsck.k9.ui.base.uiBaseModule
import com.fsck.k9.ui.changelog.changelogUiModule
import com.fsck.k9.ui.choosefolder.chooseFolderUiModule
import com.fsck.k9.ui.endtoend.endToEndUiModule
import com.fsck.k9.ui.folders.foldersUiModule
@ -29,5 +30,6 @@ val uiModules = listOf(
contactsModule,
accountModule,
autodiscoveryProvidersXmlModule,
viewModule
viewModule,
changelogUiModule
)

View file

@ -0,0 +1,104 @@
package com.fsck.k9.ui.changelog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.fsck.k9.ui.R
import de.cketti.changelog.ReleaseItem
import org.koin.android.ext.android.inject
/**
* Displays the changelog entries in a scrolling list
*/
class ChangelogFragment : Fragment() {
private val viewModel: ChangelogViewModel by inject()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_changelog, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewModel.changelogState.observe(viewLifecycleOwner, StateObserver(view))
}
class StateObserver(view: View) : Observer<ChangeLogState> {
private val loadingView: View = view.findViewById(R.id.changelog_loading)
private val errorView: View = view.findViewById(R.id.changelog_error)
private val listView: RecyclerView = view.findViewById(R.id.changelog_list)
private val allViews = setOf(loadingView, errorView, listView)
override fun onChanged(state: ChangeLogState?) {
when (state) {
is ChangeLogState.Loading -> loadingView.show()
is ChangeLogState.Error -> errorView.show()
is ChangeLogState.Data -> showChangelog(state.changeLog)
}
}
private fun showChangelog(changeLog: List<ReleaseItem>) {
listView.adapter = ChangelogAdapter(changeLog)
listView.show()
}
private fun View.show() {
for (view in allViews) {
view.isVisible = view === this
}
}
}
}
class ChangelogAdapter(releaseItems: List<ReleaseItem>) : RecyclerView.Adapter<ViewHolder>() {
private val items = releaseItems.flatMap { listOf(it) + it.changes }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view = layoutInflater.inflate(viewType, parent, false)
return when (viewType) {
R.layout.changelog_list_release_item -> ReleaseItemViewHolder(view)
R.layout.changelog_list_change_item -> ChangeItemViewHolder(view)
else -> error("Unsupported view type: $viewType")
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
when (val item = items[position]) {
is ReleaseItem -> {
val viewHolder = holder as ReleaseItemViewHolder
val context = viewHolder.versionName.context
viewHolder.versionName.text = context.getString(R.string.changelog_version_title, item.versionName)
viewHolder.versionDate.text = item.date
}
is String -> {
val viewHolder = holder as ChangeItemViewHolder
viewHolder.changeText.text = item
}
}
}
override fun getItemViewType(position: Int): Int {
return when (items[position]) {
is ReleaseItem -> R.layout.changelog_list_release_item
is String -> R.layout.changelog_list_change_item
else -> error("Unsupported item type: ${items[position]}")
}
}
override fun getItemCount(): Int = items.size
}
class ReleaseItemViewHolder(view: View) : ViewHolder(view) {
val versionName: TextView = view.findViewById(R.id.version_name)
val versionDate: TextView = view.findViewById(R.id.version_date)
}
class ChangeItemViewHolder(view: View) : ViewHolder(view) {
val changeText: TextView = view.findViewById(R.id.change_text)
}

View file

@ -0,0 +1,63 @@
package com.fsck.k9.ui.changelog
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.LiveDataScope
import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import com.fsck.k9.ui.changelog.ChangeLogState.Data
import com.fsck.k9.ui.changelog.ChangeLogState.Error
import com.fsck.k9.ui.changelog.ChangeLogState.Loading
import de.cketti.changelog.ChangeLog
import de.cketti.changelog.ReleaseItem
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
private const val PROGRESS_BAR_DELAY = 500L
class ChangelogViewModel(private val context: Context) : ViewModel() {
val changelogState: LiveData<ChangeLogState> = liveData {
coroutineScope {
loadChangelog(coroutineScope = this)
}
}
private suspend fun LiveDataScope<ChangeLogState>.loadChangelog(coroutineScope: CoroutineScope) {
val job = coroutineScope.launch {
delay(PROGRESS_BAR_DELAY)
// Show progress bar if loading took longer than configured delay. If changelog data was loaded faster
// than that, this coroutine will have been canceled before the next line is executed.
emit(Loading)
}
val finalState = try {
val data = withContext(Dispatchers.IO) {
val changeLog = ChangeLog.newInstance(context)
changeLog.changeLog
}
Data(data)
} catch (e: Exception) {
Timber.e(e, "Error loading changelog")
Error
}
// Cancel job that emits Loading state
job.cancelAndJoin()
emit(finalState)
}
}
sealed class ChangeLogState {
object Loading : ChangeLogState()
object Error : ChangeLogState()
class Data(val changeLog: List<ReleaseItem>) : ChangeLogState()
}

View file

@ -0,0 +1,8 @@
package com.fsck.k9.ui.changelog
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module
val changelogUiModule = module {
viewModel { ChangelogViewModel(context = get()) }
}

View file

@ -12,10 +12,10 @@ import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.fsck.k9.ui.R
import de.cketti.library.changelog.ChangeLog
import timber.log.Timber
class AboutFragment : Fragment() {
@ -78,7 +78,7 @@ class AboutFragment : Fragment() {
}
private fun displayChangeLog() {
ChangeLog(requireActivity()).fullLogDialog.show()
findNavController().navigate(R.id.action_aboutScreen_to_changelogScreen)
}
private fun getVersionNumber(): String {

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingTop="4dp"
android:paddingEnd="4dp"
android:paddingBottom="4dp"
android:text="•"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/change_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingTop="4dp"
android:paddingEnd="16dp"
android:paddingBottom="4dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
tools:text="Bug fixes and minor improvements" />
</LinearLayout>

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:orientation="horizontal">
<TextView
android:id="@+id/version_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="8dp"
android:paddingBottom="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
tools:text="Version 1.0.0" />
<TextView
android:id="@+id/version_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingTop="8dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:text="2021-01-21" />
</LinearLayout>

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/changelog_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="ifContentScrolls"
android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:visibility="visible" />
<ProgressBar
android:id="@+id/changelog_loading"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true"
android:visibility="gone"
tools:visibility="gone" />
<TextView
android:id="@+id/changelog_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/changelog_loading_error"
android:visibility="gone"
tools:visibility="gone" />
</FrameLayout>

View file

@ -52,7 +52,12 @@
android:id="@+id/aboutScreen"
android:name="com.fsck.k9.ui.settings.AboutFragment"
android:label="@string/about_action"
tools:layout="@layout/fragment_about"/>
tools:layout="@layout/fragment_about">
<action
android:id="@+id/action_aboutScreen_to_changelogScreen"
app:destination="@id/changelogScreen" />
</fragment>
<activity
android:id="@+id/generalSettingsScreen"
@ -77,4 +82,10 @@
android:label="@string/settings_import_title"
tools:layout="@layout/fragment_settings_import"/>
<fragment
android:id="@+id/changelogScreen"
android:name="com.fsck.k9.ui.changelog.ChangelogFragment"
android:label="@string/changelog_title"
tools:layout="@layout/fragment_changelog"/>
</navigation>

View file

@ -1,11 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="changelog_style.xsl"?>
<!--
The master change log is kept in res/xml/changelog_master.xml.
Locale specific versions are kept in res/xml-<locale qualifier>/changelog.xml.
Don't edit the changelog_<name>_branch.xml files in the gh-pages branch.
They are automatically updated with "ant bump-version".
The master change log is kept in res/raw/changelog_master.xml.
Locale-specific versions are kept in res/raw-<locale qualifier>/changelog.xml.
-->
<changelog>
<release version="5.726" versioncode="27026">
@ -47,7 +44,7 @@
<change>Added 'copy link text to clipboard' option when long-pressing links</change>
<change>Treat all whitespace as separator when detecting URLs</change>
</release>
<release version="5.720&#8203;" versioncode="27020">
<release version="5.720" versioncode="27020">
<change>Fixed bug in preview text extraction that could stop synchronization</change>
<change>When displaying text/plain parts the signature is de-emphasized</change>
<change>Sharing a message now includes subject, date, sender, and recipients</change>
@ -118,7 +115,7 @@
<change>Lots of internal changes</change>
<change>Updated translations</change>
</release>
<release version="5.710&#8203;" versioncode="27010">
<release version="5.710" versioncode="27010">
<change>Fixed duplicate message bug after moving a message</change>
<change>Removed keyboard shortcuts for menu items; on some devices they conflicted with system shortcuts</change>
<change>Don't show fullscreen keyboard in landscape mode</change>
@ -196,7 +193,7 @@
<change>Fixed bug where work was accidentally done in the main thread</change>
<change>Updated translations</change>
</release>
<release version="5.700&#8203;" versioncode="27000">
<release version="5.700" versioncode="27000">
<change>Major redesign of the user interface</change>
<change>Temporarily disabled Push (IMAP IDLE) until we can make it work reliable; your accounts will be polled every 15 minutes instead</change>
<change>Deprecated support for the WebDAV protocol; new accounts can no longer be added</change>
@ -208,7 +205,7 @@
<change>Removed the 'remote control' interface third-party apps could use to change some settings in K-9 Mail</change>
<change>Fixed a lot of bugs and probably introduced some new ones. Please report bugs.</change>
</release>
<release version="5.600&#8203;" versioncode="26000">
<release version="5.600" versioncode="26000">
<change>Allow some outdated HTML attributes so emails from popular internet services are displayed as intended</change>
<change>Fixed bug when moving or copying message (IMAP)</change>
</release>
@ -222,7 +219,7 @@
<release version="5.501" versioncode="25010">
<change>Fixed bug that lead to important files being stripped from the APK</change>
</release>
<release version="5.500&#8203;" versioncode="25000">
<release version="5.500" versioncode="25000">
<change>Further improvements to encryption user experience</change>
<change>Added ability to forward a message as attachment</change>
<change>Improved the way we display text/plain messages</change>
@ -245,7 +242,7 @@
<release version="5.401" versioncode="23610">
<change>Fixed bug that lead to some messages showing as empty</change>
</release>
<release version="5.400&#8203;" versioncode="23600">
<release version="5.400" versioncode="23600">
<change>Avoid crash on Android 8.1</change>
<change>Updated translations</change>
<change>Added Albanian translation</change>
@ -268,7 +265,7 @@
<change>Various bug fixes</change>
<change>Updated translations</change>
</release>
<release version="5.300&#8203;" versioncode="23500">
<release version="5.300" versioncode="23500">
<change>New app icon</change>
<change>New widget: Message List</change>
<change>New OpenPGP flow, adhering to Autocrypt specification</change>
@ -321,7 +318,7 @@
<change>Fixed crash during database upgrade</change>
<change>Fixed various minor bugs</change>
</release>
<release version="5.200&#8203;" versioncode="23200">
<release version="5.200" versioncode="23200">
<change>Fixed bug with status display of signed messages</change>
<change>Updated translations</change>
</release>
@ -382,7 +379,7 @@
<change>Removed broken support for sending messages as 8-bit via SMTP</change>
<change>Lots of internal changes and minor bug fixes</change>
</release>
<release version="5.110&#8203;" versioncode="23100" >
<release version="5.110" versioncode="23100" >
<change>New option: only notify for messages from contacts</change>
<change>Added auto-configuration support for more providers</change>
<change>Improved PGP/MIME experience</change>
@ -447,7 +444,7 @@
<release version="5.101" versioncode="23010">
<change>Fixed build problems that caused v5.100 to request the permissions READ_CALL_LOG and WRITE_CALL_LOG</change>
</release>
<release version="5.100&#8203;" versioncode="23000">
<release version="5.100" versioncode="23000">
<change>Removed SSL/TLS session caching because it was causing problems</change>
</release>
<release version="4.905" versioncode="21008">
@ -494,7 +491,7 @@
<change>More bug fixes</change>
<change>Updated Japanese translation</change>
</release>
<release version="4.900&#8203;" versioncode="21003" >
<release version="4.900" versioncode="21003" >
<change>Fix issue 6064: Inline images don't display on KitKat</change>
<change>Update list of German Internet providers</change>
<change>Add provider Outlook.sk and Azet.sk to provider list</change>
@ -524,7 +521,7 @@
<change>Worked around a bug in KitKat that stopped settings import from working</change>
<change>Updated German, Greek, Japanese, Korean, Lithuanian, Portugese, Russian and Slovak translations</change>
</release>
<release version="4.700&#8203;" versioncode="19001" >
<release version="4.700" versioncode="19001" >
<change>Code cleanups</change>
<change>Fixed a bug that could have caused message drafts to be sent before they were ready</change>
<change>Updates to German, Japanese, Russian, Slovak translations</change>
@ -547,7 +544,7 @@
<change>Remove icons from the "Refile" submenu, as we don't show icons in any other submenu.</change>
<change>Add icon for the copy action</change>
</release>
<release version="4.510&#8203;" versioncode="18010" >
<release version="4.510" versioncode="18010" >
<change>Fix erroneous SSL certificate warnings when connecting to a server that speaks STARTTLS</change>
<change>Updates to Russian and Slovakian translations</change>
<change>Major performance updates when opening folder lists</change>
@ -632,7 +629,7 @@
<change>Many bug fixes</change>
</release>
<release version="4.330&#8203;" versioncode="17031" >
<release version="4.330" versioncode="17031" >
<change>Changed appearance of the unread widget</change>
<change>Fixed crash when opening the app from notifications</change>
<change>Updated Finnish, Catalan translations</change>
@ -731,7 +728,7 @@
<change>Performance improvements</change>
</release>
<release version="4.320&#8203;" versioncode="17021" >
<release version="4.320" versioncode="17021" >
<change>Added 'Account settings' back to the account context menu</change>
<change>Added 'Refresh' and 'Settings' back to the folder context menu</change>
<change>Minor bug fixes</change>

View file

@ -23,6 +23,9 @@
<string name="about_twitter_title">Twitter</string>
<string name="about_libraries">Libraries</string>
<string name="license">License</string>
<string name="changelog_title">Changelog</string>
<string name="changelog_loading_error">Couldn\'t load the changelog.</string>
<string name="changelog_version_title">Version %s</string>
<!-- Welcome message -->