Commit a0816c11 authored by Ricki Hirner's avatar Ricki Hirner 🐑

Show languages in About

parent c0695075
Pipeline #124201254 passed with stages
in 9 minutes and 7 seconds
{"ar_SA":["abdunnasir"],"bg":["dpa_transifex"],"ca":["zagur"],"cs":["pavelb","tomas.odehnal"],"da":["knutztar","mjjzf","Tntdruid_","twikedk"],"de":["anestiskaci","Atalanttore","corppneq","maxkl","nicolas_git","owncube","TheName","Wyrrrd","YvanM"],"el":["anestiskaci","diamond_gr"],"es":["Ark74","Elhea","GranPC","jcvielma","plaguna","polkhas","xphnx"],"eu":["cockeredradiation","Osoitz"],"fa":["ahangarha","amiraliakbari","maryambehzi","mtashackori","Numb","taranehsaei"],"fi_FI":["raketti","tseipii"],"fr":["AlainR","alkino2","Amadeen","boutil","callmemagnus","chfo","chrcha","Floflr","grenatrad","Jorg722","Llorc","Novick","Poussinou","Thecross","YvanM","ÉricB."],"fr_FR":["chrcha","Llorc","Poussinou"],"gl":["pikamoku"],"hu":["jtg"],"it":["Damtux","ed0","FranzMari","noccio","nwandy","rickyroo","technezio"],"ja":["Naofumi"],"nb_NO":["elonus"],"nl":["davtemp","dehart","toonvangerwen","XtremeNova"],"pl":["gsz","mg6","oskarjakiela","TheName","TORminator"],"pt_BR":["amalvarenga","wanderlei.huttel"],"ru":["aigoshin","anm","astalavister","nick.savin","vaddd"],"sk_SK":["brango67","tiborepcek"],"sl_SI":["MrLaaky","uroszor"],"sr":["daimonion"],"szl":["chlodny"],"tr_TR":["ooguz","pultars"],"uk":["androsua","olexn","twixi007"],"uk_UA":["astalavister"],"zh_CN":["anolir","mofitt2016","oksjd","phy"],"zh_TW":["mofitt2016","phy"]}
......@@ -14,7 +14,9 @@ import android.os.Bundle
import android.text.Spanned
import android.util.DisplayMetrics
import android.view.*
import androidx.annotation.UiThread
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.core.text.HtmlCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
......@@ -23,13 +25,18 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import at.bitfire.davdroid.App
import at.bitfire.davdroid.BuildConfig
import at.bitfire.davdroid.R
import com.mikepenz.aboutlibraries.LibsBuilder
import kotlinx.android.synthetic.main.about.*
import kotlinx.android.synthetic.main.about_languages.*
import kotlinx.android.synthetic.main.about_translation.view.*
import kotlinx.android.synthetic.main.activity_about.*
import org.apache.commons.io.IOUtils
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.*
import kotlin.concurrent.thread
......@@ -70,17 +77,19 @@ class AboutActivity: AppCompatActivity() {
fm: FragmentManager
): FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getCount() = 2
override fun getCount() = 3
override fun getPageTitle(position: Int): String =
when (position) {
0 -> getString(R.string.app_name)
1 -> getString(R.string.about_languages)
else -> getString(R.string.about_libraries)
}
override fun getItem(position: Int) =
when (position) {
0 -> AppFragment()
1 -> LanguagesFragment()
else -> LibsBuilder()
.withAutoDetect(false)
.withFields(R.string::class.java.fields)
......@@ -108,7 +117,8 @@ class AboutActivity: AppCompatActivity() {
if (true /* open-source version */) {
warranty.setText(R.string.about_license_info_no_warranty)
val model = ViewModelProvider(this).get(LicenseModel::class.java)
val model = ViewModelProvider(this).get(TextFileModel::class.java)
model.initialize("gplv3.html", true)
model.htmlText.observe(viewLifecycleOwner, Observer { spanned ->
license_text.text = spanned
})
......@@ -117,19 +127,116 @@ class AboutActivity: AppCompatActivity() {
}
class LicenseModel(
class LanguagesFragment: Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) =
inflater.inflate(R.layout.about_languages, container, false)!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val model = ViewModelProvider(this).get(TextFileModel::class.java)
model.initialize("translators.json", false)
model.plainText.observe(viewLifecycleOwner, Observer { json ->
val jsonTranslations = JSONObject(json)
translators.adapter = TranslationsAdapter(jsonTranslations)
/*for (locale in Locale.getAvailableLocales()) {
text.append(locale.toLanguageTag()).append("<br/>")
}
for (langCode in languages.keys()) {
text.append(langCode).append("<br/>")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
text.append(langCode).append("<br/>")
val langTag = langCode.replace('_', '-')
text.append(Locale.forLanguageTag(langTag).displayName).append("<br/>")
}
val translators = langCode.getJSONArray("translators")
for (j in 0 until translators.length()) {
val translator = translators.getString(j)
text.append("@").append(translator).append(" (Transifex)<br/>")
}
text.append("<br/>")
}
translators.setText(HtmlCompat.fromHtml(text.toString(), HtmlCompat.FROM_HTML_MODE_COMPACT))*/
})
translators.layoutManager = LinearLayoutManager(requireActivity())
}
class Translation(
val langCode: String,
val translators: Array<String>
)
class TranslationsAdapter(
jsonTranslations: JSONObject
): RecyclerView.Adapter<TranslationsAdapter.ViewHolder>() {
class ViewHolder(val cardView: CardView): RecyclerView.ViewHolder(cardView)
private val translations = LinkedList<Translation>()
init {
for (langCode in jsonTranslations.keys()) {
val jsonTranslators = jsonTranslations.getJSONArray(langCode)
val translators = Array<String>(jsonTranslators.length()) {
idx -> jsonTranslators.getString(idx)
}
translations += Translation(langCode, translators)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val tv = LayoutInflater.from(parent.context).inflate(R.layout.about_translation, parent, false) as CardView
return ViewHolder(tv)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val translation = translations[position]
holder.cardView.apply {
languageCode.text = translation.langCode
val langTag = translation.langCode.replace('_', '-')
language.text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
Locale.forLanguageTag(langTag).displayName
else
langTag
translators.text = translation.translators.joinToString(" · ")
}
}
override fun getItemCount() = translations.size
}
}
class TextFileModel(
application: Application
): AndroidViewModel(application) {
var initialized = false
val htmlText = MutableLiveData<Spanned>()
val plainText = MutableLiveData<String>()
@UiThread
fun initialize(assetName: String, html: Boolean) {
if (initialized) return
init {
thread {
getApplication<Application>().resources.assets.open("gplv3.html").use {
val spanned = HtmlCompat.fromHtml(IOUtils.toString(it, Charsets.UTF_8), HtmlCompat.FROM_HTML_MODE_LEGACY)
htmlText.postValue(spanned)
getApplication<Application>().resources.assets.open(assetName).use {
val raw = IOUtils.toString(it, Charsets.UTF_8)
if (html) {
val spanned = HtmlCompat.fromHtml(raw, HtmlCompat.FROM_HTML_MODE_LEGACY)
htmlText.postValue(spanned)
} else
plainText.postValue(raw)
}
}
initialized = true
}
}
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/translators"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/activity_margin" />
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:contentPadding="8dp"
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/language"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
tools:text="Sample Language"
android:textAppearance="@style/TextView.Heading"/>
<TextView
android:id="@+id/languageCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:fontFamily="monospace"
tools:text="xx-yy"/>
</LinearLayout>
<TextView
android:id="@+id/translators"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
......@@ -50,6 +50,7 @@
<string name="startup_opentasks_not_installed_install">Install OpenTasks</string>
<!-- AboutActivity -->
<string name="about_languages">Languages</string>
<string name="about_libraries">Libraries</string>
<string name="about_version">Version %1$s (%2$d)</string>
<string name="about_build_date">Compiled on %s</string>
......
......@@ -42,3 +42,5 @@ do
fetch_txt "https://www.transifex.com/api/2/project/davx5/resource/metadata-full-description/translation/$lang?file" ${android[$lang]} full_description.txt
fetch_txt "https://www.transifex.com/api/2/project/davx5/resource/metadata-short-description/translation/$lang?file" ${android[$lang]} short_description.txt
done
curl -n https://www.transifex.com/api/2/project/davx5/languages/ | ./rewrite-translators.rb >../app/src/main/assets/translators.json
#!/usr/bin/ruby
require 'json'
contributors = {}
transifex = JSON.parse(STDIN.read, :symbolize_names => true)
for t in transifex
lang = t[:language_code]
people = t[:translators]
contributors[lang] = people.sort_by { |nick| nick.downcase }
end
puts contributors.sort.to_h.to_json
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment