diff --git a/app/build.gradle b/app/build.gradle
index e68f83a6..5be5e06c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -22,7 +22,7 @@ android {
minSdkVersion min_sdk_version
versionCode 402
- versionName "4.0.2"
+ versionName "4.0.2x"
applicationId "jp.juggler.subwaytooter"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActLanguageFilter.kt b/app/src/main/java/jp/juggler/subwaytooter/ActLanguageFilter.kt
index 452fd86f..b48b012b 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/ActLanguageFilter.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/ActLanguageFilter.kt
@@ -5,6 +5,7 @@ import android.content.Intent
import android.net.Uri
import android.os.AsyncTask
import android.os.Bundle
+import android.os.PersistableBundle
import android.os.Process
import android.text.Editable
import android.text.TextWatcher
@@ -38,6 +39,7 @@ class ActLanguageFilter : AppCompatActivity(), View.OnClickListener {
internal val log = LogCategory("ActLanguageFilter")
internal const val EXTRA_COLUMN_INDEX = "column_index"
+ private const val STATE_LANGUAGE_LIST = "language_list"
fun open(activity : ActMain, idx : Int, request_code : Int) {
val intent = Intent(activity, ActLanguageFilter::class.java)
@@ -59,6 +61,19 @@ class ActLanguageFilter : AppCompatActivity(), View.OnClickListener {
}
}
+ private fun equalsLanguageList(a : JsonObject?, b : JsonObject?) : Boolean {
+ fun JsonObject.encodeToString() : String {
+ val clone = this.toString().decodeJsonObject()
+ if(! clone.contains(TootStatus.LANGUAGE_CODE_DEFAULT)) {
+ clone[TootStatus.LANGUAGE_CODE_DEFAULT] = true
+ }
+ return clone.keys.sorted().joinToString(",") { "$it=${this[it]}" }
+ }
+
+ val a_sign = (a ?: JsonObject()).encodeToString()
+ val b_sign = (b ?: JsonObject()).encodeToString()
+ return a_sign == b_sign
+ }
}
private val languageNameMap by lazy {
@@ -94,6 +109,7 @@ class ActLanguageFilter : AppCompatActivity(), View.OnClickListener {
put(TootStatus.LANGUAGE_CODE_DEFAULT, getString(R.string.language_code_default))
put(TootStatus.LANGUAGE_CODE_UNKNOWN, getString(R.string.language_code_unknown))
}
+
}
private fun getDesc(item : MyItem) : String {
@@ -121,9 +137,39 @@ class ActLanguageFilter : AppCompatActivity(), View.OnClickListener {
column_index = intent.getIntExtra(EXTRA_COLUMN_INDEX, 0)
column = app_state.column_list[column_index]
+ if(savedInstanceState != null) {
+ try {
+ val sv = savedInstanceState.getString(STATE_LANGUAGE_LIST, null)
+ if(sv != null) {
+ val list = sv.decodeJsonObject()
+ load(list)
+ return
+ }
+ } catch(ex : Throwable) {
+ log.trace(ex)
+ }
+ }
load(column.language_filter)
}
+ override fun onSaveInstanceState(outState : Bundle, outPersistentState : PersistableBundle) {
+ super.onSaveInstanceState(outState, outPersistentState)
+ outState.putString(STATE_LANGUAGE_LIST, encodeLanguageList().toString())
+ }
+
+ override fun onBackPressed() {
+ if(! equalsLanguageList(column.language_filter, encodeLanguageList())) {
+ AlertDialog.Builder(this)
+ .setMessage(R.string.language_filter_quit_waring)
+ .setPositiveButton(R.string.ok) { _, _ -> finish() }
+ .setNegativeButton(R.string.cancel, null)
+ .show()
+ return
+ }
+
+ super.onBackPressed()
+ }
+
private fun initUI() {
setContentView(R.layout.act_language_filter)
App1.initEdgeToEdge(this)
@@ -143,21 +189,30 @@ class ActLanguageFilter : AppCompatActivity(), View.OnClickListener {
listView.onItemClickListener = adapter
}
+ // UIのデータをJsonObjectにエンコード
+ private fun encodeLanguageList() = jsonObject {
+ for(item in languageList) {
+ put(item.code, item.allow)
+ }
+ }
+
private fun load(src : JsonObject?) {
loading_busy = true
try {
-
languageList.clear()
+
if(src != null) {
for(key in src.keys) {
languageList.add(MyItem(key, src.boolean(key) ?: true))
}
}
+
if(null == languageList.find { it.code == TootStatus.LANGUAGE_CODE_DEFAULT }) {
languageList.add(MyItem(TootStatus.LANGUAGE_CODE_DEFAULT, true))
}
languageList.sortWith(languageComparator)
+
adapter.notifyDataSetChanged()
} finally {
loading_busy = false
@@ -165,11 +220,7 @@ class ActLanguageFilter : AppCompatActivity(), View.OnClickListener {
}
private fun save() {
- column.language_filter = jsonObject {
- for(item in languageList) {
- put(item.code, item.allow)
- }
- }
+ column.language_filter = encodeLanguageList()
}
private inner class MyAdapter : BaseAdapter(), AdapterView.OnItemClickListener {
diff --git a/app/src/main/java/jp/juggler/subwaytooter/AppDataExporter.kt b/app/src/main/java/jp/juggler/subwaytooter/AppDataExporter.kt
index 6d37dc60..8697b00e 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/AppDataExporter.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/AppDataExporter.kt
@@ -41,82 +41,76 @@ object AppDataExporter {
private const val KEY_HIGHLIGHT_WORD = "highlight_word"
@Throws(IOException::class, JsonException::class)
- private fun writeJSONObject(writer : JsonWriter, src : JsonObject) {
+ private fun writeJsonValue(writer : JsonWriter, value:Any?) {
+ when(value) {
+ null -> writer.nullValue()
+ is String -> writer.value(value)
+ is Boolean -> writer.value(value)
+ is Number -> writer.value(value)
+ is EntityId -> writer.value(value.toString())
+ is JsonObject -> writeJsonObject(writer,value)
+ is JsonArray ->writeJsonArray(writer,value)
+ else -> throw RuntimeException("writeJsonValue: bad data type: $value")
+ }
+ }
+
+ @Throws(IOException::class, JsonException::class)
+ private fun writeJsonArray(writer : JsonWriter, src : JsonArray) {
+ writer.beginArray()
+ for( value in src) {
+ writeJsonValue(writer,value)
+ }
+ writer.endArray()
+ }
+
+ @Throws(IOException::class, JsonException::class)
+ private fun writeJsonObject(writer : JsonWriter, src : JsonObject) {
writer.beginObject()
- val it = src.keys.iterator()
- while(it.hasNext()) {
- val k = it.next()
- if(src.isNull(k)) {
- writer.name(k)
- writer.nullValue()
- } else {
- when(val o = src[k]) {
- is String -> {
- writer.name(k)
- writer.value(o)
-
- }
-
- is Boolean -> {
- writer.name(k)
- writer.value(o)
-
- }
-
- is Number -> {
-
- writer.name(k)
- writer.value(o)
-
- }
-
- is EntityId -> {
- writer.name(k)
- writer.value(o.toString())
- }
-
- else -> throw RuntimeException(
- String.format(
- Locale.JAPAN,
- "bad data type: JsonObject key =%s",
- k
- )
- )
- }
- }
+ for( entry in src.entries){
+ writer.name(entry.key)
+ writeJsonValue(writer, entry.value)
}
writer.endObject()
}
@Throws(IOException::class, JsonException::class)
- private fun readJsonObject(reader : JsonReader) : JsonObject {
- val dst = JsonObject()
+ private fun readJsonValue(reader:JsonReader):Any?{
+ return when(val token = reader.peek()) {
+ JsonToken.NULL -> {
+ reader.nextNull()
+ null
+ }
+
+ JsonToken.STRING -> reader.nextString()
+ JsonToken.BOOLEAN -> reader.nextBoolean()
+ JsonToken.NUMBER -> reader.nextDouble()
+ JsonToken.BEGIN_ARRAY -> readJsonArray(reader)
+ JsonToken.BEGIN_OBJECT -> readJsonObject(reader)
+ else -> null
+ }
+ }
+
+ @Throws(IOException::class, JsonException::class)
+ private fun readJsonArray(reader:JsonReader):JsonArray{
+ val dst = JsonArray()
+ reader.beginArray()
+ while(reader.hasNext()) {
+ dst.add(readJsonValue(reader))
+ }
+ reader.endArray()
+ return dst
+ }
+ @Throws(IOException::class, JsonException::class)
+ private fun readJsonObject(reader:JsonReader):JsonObject{
+ val dst = JsonObject()
reader.beginObject()
while(reader.hasNext()) {
val name = reader.nextName()
- when(val token = reader.peek()) {
-
- JsonToken.NULL -> reader.nextNull()
-
- JsonToken.STRING -> dst[name] = reader.nextString()
-
- JsonToken.BOOLEAN -> dst[name] = reader.nextBoolean()
-
- JsonToken.NUMBER -> dst[name] = reader.nextDouble()
-
- else -> throw RuntimeException(
- String.format(
- Locale.JAPAN,
- "bad data type: %s key =%s",
- token,
- name
- )
- )
- }
+ val value = readJsonValue(reader)
+ dst[name]=value
}
reader.endObject()
-
return dst
}
@@ -329,7 +323,7 @@ object AppDataExporter {
for(column in app_state.column_list) {
val dst = JsonObject()
column.encodeJSON(dst, 0)
- writeJSONObject(writer, dst)
+ writeJsonObject(writer, dst)
}
writer.endArray()
}
diff --git a/app/src/main/java/jp/juggler/subwaytooter/action/CustomShare.kt b/app/src/main/java/jp/juggler/subwaytooter/action/CustomShare.kt
index 973f3ba2..03c6612c 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/action/CustomShare.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/action/CustomShare.kt
@@ -1,10 +1,8 @@
package jp.juggler.subwaytooter.action
import android.content.*
-import android.content.pm.PackageManager
import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
-import android.net.Uri
import androidx.core.content.ContextCompat
import jp.juggler.subwaytooter.App1
import jp.juggler.subwaytooter.Pref
diff --git a/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.kt b/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.kt
index 12c1594c..56c46ddd 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootStatus.kt
@@ -1054,14 +1054,15 @@ class TootStatus(parser : TootParser, src : JsonObject) : TimelineItem() {
}
}
- return formatDate(t,date_format,omitZeroSecond = false)
+ return formatDate(t,date_format,omitZeroSecond = false,omitYear = false)
}
// 告知の開始/終了日付
private fun formatDate(
t : Long,
format:SimpleDateFormat ,
- omitZeroSecond:Boolean
+ omitZeroSecond:Boolean,
+ omitYear:Boolean
) : String {
var dateTarget = format.format(Date(t))
@@ -1071,10 +1072,15 @@ class TootStatus(parser : TootParser, src : JsonObject) : TimelineItem() {
}
// 年の部分が現在と同じなら省略する
- val dateNow = format.format(Date())
- val delm = dateNow.indexOf('-')
- if(delm!=-1 && dateNow.substring(0,delm+1) == dateTarget.substring(0,delm+1)){
- dateTarget = dateTarget.substring(delm+1)
+ if(omitYear) {
+ val dateNow = format.format(Date())
+ val delm = dateNow.indexOf('-')
+ if(delm != - 1 && dateNow.substring(0, delm + 1) == dateTarget.substring(
+ 0,
+ delm + 1
+ )) {
+ dateTarget = dateTarget.substring(delm + 1)
+ }
}
return dateTarget
@@ -1083,13 +1089,13 @@ class TootStatus(parser : TootParser, src : JsonObject) : TimelineItem() {
fun formatTimeRange(start : Long, end : Long, allDay : Boolean):Pair{
val strStart = when {
start <= 0L -> ""
- allDay-> formatDate(start,date_format2,omitZeroSecond = false)
- else -> formatDate(start, date_format,omitZeroSecond = true)
+ allDay-> formatDate(start,date_format2,omitZeroSecond = false,omitYear = true)
+ else -> formatDate(start, date_format,omitZeroSecond = true,omitYear = true)
}
val strEnd = when {
end <= 0L -> ""
- allDay-> formatDate(end,date_format2,omitZeroSecond = false)
- else -> formatDate(end, date_format,omitZeroSecond = true)
+ allDay-> formatDate(end,date_format2,omitZeroSecond = false,omitYear = true)
+ else -> formatDate(end, date_format,omitZeroSecond = true,omitYear = true)
}
// 終了日は先頭と同じ部分を省略する
var skip = 0
diff --git a/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgAppPicker.kt b/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgAppPicker.kt
index a688d703..e6ca6af9 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgAppPicker.kt
+++ b/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgAppPicker.kt
@@ -4,8 +4,6 @@ import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Intent
import android.content.pm.PackageManager
-import android.content.pm.ResolveInfo
-import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import android.os.Build
import android.view.View
@@ -13,7 +11,6 @@ import android.view.ViewGroup
import android.view.WindowManager
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
-import androidx.core.content.ContextCompat
import jp.juggler.subwaytooter.R
import jp.juggler.subwaytooter.action.CustomShare
import jp.juggler.subwaytooter.action.cn
diff --git a/app/src/main/res/layout/lv_app_picker.xml b/app/src/main/res/layout/lv_app_picker.xml
index c2a90604..fb9d9627 100644
--- a/app/src/main/res/layout/lv_app_picker.xml
+++ b/app/src/main/res/layout/lv_app_picker.xml
@@ -1,7 +1,7 @@
サーバが古い間に作られた投稿は(サーバがアップデートした後でも)EmojiOneのショートコードを含むかもしれません。
クリップボードにコピー
クリップボードにコピーしました
+ Language filter is not saved. exit anyway?
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5aefaf20..4ab39d5b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1006,4 +1006,5 @@
The toots made by old Mastodon may contain emojione\'s shortcode even if the server have been updated.
Copy to clipboard
Copied to clipboard.
+ Language filter is not saved. exit anyway?
\ No newline at end of file