Improve messages, fix back button, navbar theme
- New Feature: Improve error messages for the user - Create Toaster Class to deal with toast notifications - Bugfix: Back button now enabled in fresh install - Update navbar theme (dark/light rather than the app accent colour) - Update gradle, changelog - Use dataExtractionRules - Spellings
This commit is contained in:
parent
a0b775225d
commit
22f1b38da1
@ -7,13 +7,20 @@ patch-level version changes can be found in [commit messages](../../commits/mast
|
||||
## Next_Ver - 2022/xx/xx
|
||||
-->
|
||||
|
||||
## Next_Ver - 2022/xx/xx
|
||||
|
||||
- New Feature: Improve error messages for the user per https://github.com/FredHappyface/Android.EweSticker/issues/39
|
||||
- Bugfix: Back button now enabled in fresh install per https://github.com/FredHappyface/Android.EweSticker/issues/38
|
||||
- Update navbar theme (dark/light rather than the app accent colour)
|
||||
- Update dependencies
|
||||
|
||||
## 20220128 - 2022/01/28
|
||||
|
||||
- Highlight the selected tab. https://github.com/FredHappyface/Android.EweSticker/issues/29
|
||||
- Add support for video formats https://github.com/FredHappyface/Android.EweSticker/issues/34
|
||||
- "video/3gpp", "video/mp4", "video/x-matroska", "video/webm"
|
||||
- Reformat
|
||||
- Update deps
|
||||
- Update dependencies
|
||||
- Limit sticker pack size to resolve `java.lang.OutOfMemoryError: at androidx.gridlayout.widget.GridLayout`
|
||||
|
||||
## 20220103 - 2022/01/03
|
||||
|
@ -35,7 +35,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.5.31")
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.0")
|
||||
implementation("androidx.core:core-ktx:1.7.0")
|
||||
implementation("androidx.appcompat:appcompat:1.4.1")
|
||||
implementation("com.google.android.material:material:1.5.0")
|
||||
|
@ -7,12 +7,12 @@
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
tools:ignore="GoogleAppIndexingWarning">
|
||||
tools:ignore="GoogleAppIndexingWarning"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules">
|
||||
<activity
|
||||
android:name="com.fredhappyface.ewesticker.MainActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
@ -12,7 +12,6 @@ import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageButton
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.view.inputmethod.EditorInfoCompat
|
||||
@ -52,6 +51,7 @@ class ImageKeyboard : InputMethodService() {
|
||||
// Constants
|
||||
private lateinit var internalDir: File
|
||||
private var totalIconPadding = 0
|
||||
private lateinit var toaster: Toaster
|
||||
|
||||
// Load Packs
|
||||
private lateinit var loadedPacks: HashMap<String, StickerPack>
|
||||
@ -112,6 +112,7 @@ class ImageKeyboard : InputMethodService() {
|
||||
(this.sharedPreferences.getInt("iconSize", 80) * scale)
|
||||
})
|
||||
.toInt()
|
||||
this.toaster = Toaster(applicationContext)
|
||||
// Load Packs
|
||||
this.loadedPacks = HashMap()
|
||||
val packs =
|
||||
@ -206,10 +207,7 @@ class ImageKeyboard : InputMethodService() {
|
||||
private suspend fun doFallbackCommitContent(file: File) {
|
||||
// PNG might not be supported
|
||||
if ("image/png" !in this.supportedMimes) {
|
||||
Toast.makeText(
|
||||
applicationContext, file.extension + " not supported here.", Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
toaster.toast(getString(R.string.fallback_040, file.extension))
|
||||
return
|
||||
}
|
||||
// Create a new compatSticker and convert the sticker to png
|
||||
@ -231,6 +229,7 @@ class ImageKeyboard : InputMethodService() {
|
||||
.build()
|
||||
imageLoader.execute(request)
|
||||
} catch (ignore: IOException) {
|
||||
toaster.toast(getString(R.string.fallback_041))
|
||||
}
|
||||
}
|
||||
// Send the compatSticker!
|
||||
@ -317,7 +316,11 @@ class ImageKeyboard : InputMethodService() {
|
||||
}
|
||||
// Swap the image container
|
||||
this.packContent.removeAllViewsInLayout()
|
||||
packLayout.parent ?: this.packContent.addView(packLayout)
|
||||
if (packLayout.parent != null) {
|
||||
toaster.toast(getString(R.string.switch_050))
|
||||
} else {
|
||||
this.packContent.addView(packLayout)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -405,7 +408,7 @@ class ImageKeyboard : InputMethodService() {
|
||||
private fun createPackIcons() {
|
||||
this.packsList.removeAllViewsInLayout()
|
||||
// Back button
|
||||
if (this.sharedPreferences.getBoolean("showBackButton", false)) {
|
||||
if (this.sharedPreferences.getBoolean("showBackButton", true)) {
|
||||
val backButton = addPackButton("__back__")
|
||||
backButton.load(getDrawable(R.drawable.ic_chevron_left))
|
||||
backButton.setOnClickListener {
|
||||
|
@ -18,7 +18,6 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.util.*
|
||||
@ -35,6 +34,7 @@ class MainActivity : AppCompatActivity() {
|
||||
// onCreate
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
private lateinit var contextView: View
|
||||
private lateinit var toaster: Toaster
|
||||
|
||||
// importSticker(s)
|
||||
private var filesLeft = MAX_FILES
|
||||
@ -53,6 +53,7 @@ class MainActivity : AppCompatActivity() {
|
||||
// Set late-init attrs
|
||||
this.sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
this.contextView = findViewById(R.id.activityMainRoot)
|
||||
this.toaster = Toaster(applicationContext)
|
||||
refreshStickerDirPath()
|
||||
// Update UI with config
|
||||
seekBar(findViewById(R.id.iconsPerXSb), findViewById(R.id.iconsPerXLbl), "iconsPerX", 3)
|
||||
@ -116,8 +117,11 @@ class MainActivity : AppCompatActivity() {
|
||||
// Exit if sticker is unsupported or if pack size > MAX_PACK_SIZE
|
||||
val parentDir = sticker.parentFile?.name ?: "__default__"
|
||||
val packSize = this.packSizes[parentDir] ?: 0
|
||||
if (sticker.type !in this.supportedMimes || packSize > MAX_PACK_SIZE) {
|
||||
return
|
||||
if (packSize > MAX_PACK_SIZE) {
|
||||
this.toaster.setState(2); return
|
||||
}
|
||||
if (sticker.type !in this.supportedMimes) {
|
||||
this.toaster.setState(3); return
|
||||
}
|
||||
this.packSizes[parentDir] = packSize + 1
|
||||
// Copy sticker to app storage
|
||||
@ -137,12 +141,9 @@ class MainActivity : AppCompatActivity() {
|
||||
// Use worker thread because this takes several seconds
|
||||
val executor = Executors.newSingleThreadExecutor()
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
Snackbar.make(
|
||||
this.contextView,
|
||||
"Starting import. You will not be able to reselect directory until finished. This might take a bit!",
|
||||
Snackbar.LENGTH_LONG
|
||||
toaster.toast(
|
||||
getString(R.string.imported_010),
|
||||
)
|
||||
.show()
|
||||
val button = findViewById<Button>(R.id.updateStickerPackInfoBtn)
|
||||
button.isEnabled = false
|
||||
executor.execute {
|
||||
@ -153,16 +154,21 @@ class MainActivity : AppCompatActivity() {
|
||||
)
|
||||
val leafNodes =
|
||||
fileWalk(DocumentFile.fromTreeUri(applicationContext, Uri.parse(stickerDirPath)))
|
||||
if (leafNodes.size > MAX_FILES) {
|
||||
toaster.setState(1)
|
||||
}
|
||||
for (file in leafNodes.take(MAX_FILES)) {
|
||||
importSticker(file)
|
||||
}
|
||||
handler.post {
|
||||
Snackbar.make(
|
||||
this.contextView,
|
||||
"Imported ${this.totalStickers} stickers. You may need to reload the keyboard for new stickers to show up.",
|
||||
Snackbar.LENGTH_LONG
|
||||
toaster.toastOnState(
|
||||
arrayOf(
|
||||
getString(R.string.imported_020, this.totalStickers),
|
||||
getString(R.string.imported_031, this.totalStickers),
|
||||
getString(R.string.imported_032, this.totalStickers),
|
||||
getString(R.string.imported_033, this.totalStickers),
|
||||
)
|
||||
)
|
||||
.show()
|
||||
val editor = this.sharedPreferences.edit()
|
||||
editor.putInt("numStickersImported", this.totalStickers)
|
||||
editor.apply()
|
||||
@ -274,11 +280,8 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
/** Reusable function to warn about changing preferences */
|
||||
internal fun showChangedPrefText() {
|
||||
Snackbar.make(
|
||||
this.contextView,
|
||||
"Preferences changed. You may need to reload the keyboard for settings to apply.",
|
||||
Snackbar.LENGTH_SHORT
|
||||
this.toaster.toast(
|
||||
getString(R.string.pref_000)
|
||||
)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
75
app/src/main/java/com/fredhappyface/ewesticker/Toaster.kt
Normal file
75
app/src/main/java/com/fredhappyface/ewesticker/Toaster.kt
Normal file
@ -0,0 +1,75 @@
|
||||
package com.fredhappyface.ewesticker
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
|
||||
/**
|
||||
* The Toaster class provides a simplified interface to android.widget.Toast. Pass in the
|
||||
* android.content.Context to the constructor and call the 'toast' function (others as below)
|
||||
* toaster.state keeps track of an error state or similar.
|
||||
*
|
||||
* @property context: android.content.Context. e.g. applicationContext
|
||||
*/
|
||||
class Toaster(private val context: Context) {
|
||||
private var state = 0
|
||||
|
||||
/**
|
||||
* Call toaster.toast with some string to always create a toast notification. Context is set when
|
||||
* Toaster is instantiated. Duration is determined based on text length
|
||||
*
|
||||
* @param string: String. Message to output
|
||||
*/
|
||||
fun toast(string: String) {
|
||||
Toast.makeText(
|
||||
this.context, string, if (string.length > 60) {
|
||||
Toast.LENGTH_LONG
|
||||
} else {
|
||||
Toast.LENGTH_SHORT
|
||||
}
|
||||
)
|
||||
.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Call toaster.toastOnState with an array of messages to create a toast notification.
|
||||
* Context is set when Toaster is instantiated. Duration is determined based on
|
||||
* text length. The message is selected based on the state (which can be set in a callback
|
||||
* function or elsewhere
|
||||
*
|
||||
* @param strings: Array<String>. Array of potential messages to output.
|
||||
*/
|
||||
fun toastOnState(strings: Array<String>) {
|
||||
if (this.state < strings.size) {
|
||||
this.toast(strings[this.state])
|
||||
} else {
|
||||
this.toast("toaster.state=${this.state} out of range strings.size=${strings.size}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call toaster.toastOnNonZero with a messages to create a toast notification of the state is
|
||||
* not zero. Context is set when Toaster is instantiated. Duration is determined based on
|
||||
* text length.
|
||||
*
|
||||
* @param string: String. Message to output
|
||||
*/
|
||||
fun toastOnNonZero(string: String) {
|
||||
if (this.state != 0) {
|
||||
toast(string)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the state to some integer value
|
||||
*
|
||||
* @param state: Int
|
||||
*/
|
||||
fun setState(state: Int) {
|
||||
if (state < 0) {
|
||||
this.state = 0
|
||||
} else {
|
||||
this.state = state
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -53,4 +53,14 @@ Copyright © Randy Zhou</string>
|
||||
<string name="links_text">"- Proyecto: https://github.com/FredHappyface/Android.EweSticker
|
||||
- Tutorial: https://github.com/FredHappyface/Android.EweSticker/blob/main/TUTORIAL.md
|
||||
- Licencia: https://github.com/FredHappyface/Android.EweSticker/blob/main/LICENSE.md</string>
|
||||
<!-- Interactive Messages -->
|
||||
<string name="pref_000">Preferencias cambiadas.Actualizar el teclado para configurar para aplicar</string>
|
||||
<string name="imported_010">Entendiendo la importación.¡Esto podría llevar algún tiempo!</string>
|
||||
<string name="imported_020">Importado %1$d pegatinas.Actualizar el teclado para nuevas etiquetas engomadas para mostrar</string>
|
||||
<string name="imported_031">E031: Algunos pegatinas no se importaron (%1$d importado).Pegatinas max alcanzadas</string>
|
||||
<string name="imported_032">E032: Algunos pegatinas no importaron (%1$d importado).Tamaño máximo del paquete alcanzado</string>
|
||||
<string name="imported_033">E033: Algunos pegatinas no importaron (%1$d importado).Formatos no compatibles encontrados</string>
|
||||
<string name="fallback_040">E040: %1$s no admitido aquí</string>
|
||||
<string name="fallback_041">E041: IOException inesperado al convertir la pegatina</string>
|
||||
<string name="switch_050">E050: IlegalStateException cuando cambia los paquetes.Intenta alejarse de y volver a Ewesticker</string>
|
||||
</resources>
|
||||
|
@ -3,4 +3,5 @@
|
||||
<color name="bg">#181a1f</color>
|
||||
<color name="fg">#e6e6e6</color>
|
||||
<color name="sticker">#21252b</color>
|
||||
<bool name="light_theme">false</bool>
|
||||
</resources>
|
||||
|
29
app/src/main/res/values-v27/styles.xml
Normal file
29
app/src/main/res/values-v27/styles.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimaryVariant">@color/accent</item>
|
||||
<item name="colorOnPrimary">@color/onAccent</item>
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="android:windowLightNavigationBar">@bool/light_theme</item>
|
||||
<item name="android:navigationBarColor">@color/bg</item>
|
||||
<item name="colorPrimaryDark">@color/accent</item>
|
||||
<item name="colorPrimary">@color/accent</item>
|
||||
<item name="colorAccent">@color/accent</item>
|
||||
<item name="android:textColorPrimary">@color/fg</item>
|
||||
<item name="android:textColorSecondary">@color/fg</item>
|
||||
<item name="android:textColor">@color/fg</item>
|
||||
<item name="android:windowBackground">@color/bg</item>
|
||||
<item name="actionOverflowButtonStyle">@style/OverflowButtonStyle</item>
|
||||
<item name="actionBarStyle">@style/AppBarBackground</item>
|
||||
<item name="actionBarTheme">@style/AppBarText</item>
|
||||
<item name="android:fontFamily">@font/firasans_bold</item>
|
||||
<item name="colorSurface">@color/sticker</item>
|
||||
<item name="colorOnSurface">@color/fg</item>
|
||||
<item name="shapeAppearanceMediumComponent">@style/ShapeAppearance.App.MediumComponent
|
||||
</item>
|
||||
<item name="snackbarStyle">@style/Widget.App.Snackbar</item>
|
||||
<item name="snackbarTextViewStyle">@style/Widget.App.Snackbar.TextView</item>
|
||||
</style>
|
||||
</resources>
|
@ -54,4 +54,14 @@ Copyright © Randy Zhou</string>
|
||||
<string name="links_text">"- Project: https://github.com/FredHappyface/Android.EweSticker
|
||||
- Tutorial: https://github.com/FredHappyface/Android.EweSticker/blob/main/TUTORIAL.md
|
||||
- License: https://github.com/FredHappyface/Android.EweSticker/blob/main/LICENSE.md</string>
|
||||
<!-- Interactive Messages -->
|
||||
<string name="pref_000">Preferences changed. Reload the keyboard for settings to apply</string>
|
||||
<string name="imported_010">Starting import. This might take some time!</string>
|
||||
<string name="imported_020">Imported %1$d stickers. Reload the keyboard for new stickers to show</string>
|
||||
<string name="imported_031">E031: Some stickers failed to import (%1$d imported). Max stickers reached</string>
|
||||
<string name="imported_032">E032: Some stickers failed to import (%1$d imported). Max pack size reached</string>
|
||||
<string name="imported_033">E033: Some stickers failed to import (%1$d imported). Unsupported formats found</string>
|
||||
<string name="fallback_040">E040: %1$s not supported here</string>
|
||||
<string name="fallback_041">E041: Unexpected IOException when converting sticker</string>
|
||||
<string name="switch_050">E050: IllegalStateException when switching packs. Try switching away from and back to EweSticker</string>
|
||||
</resources>
|
||||
|
@ -3,4 +3,5 @@
|
||||
<color name="bg">#f0f0f1</color>
|
||||
<color name="fg">#383a42</color>
|
||||
<color name="sticker">#e7e7e9</color>
|
||||
<bool name="light_theme">true</bool>
|
||||
</resources>
|
||||
|
36
app/src/main/res/xml/data_extraction_rules.xml
Normal file
36
app/src/main/res/xml/data_extraction_rules.xml
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Sample data extraction rules file; uncomment and customize as necessary.
|
||||
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
||||
for details.
|
||||
-->
|
||||
<data-extraction-rules>
|
||||
<cloud-backup>
|
||||
<!--
|
||||
TODO: Use <include> and <exclude> to control what is backed up.
|
||||
The domain can be file, database, sharedpref, external or root.
|
||||
Examples:
|
||||
|
||||
<include domain="file" path="file_to_include"/>
|
||||
<exclude domain="file" path="file_to_exclude"/>
|
||||
<include domain="file" path="include_folder"/>
|
||||
<exclude domain="file" path="include_folder/file_to_exclude"/>
|
||||
<exclude domain="file" path="exclude_folder"/>
|
||||
<include domain="file" path="exclude_folder/file_to_include"/>
|
||||
|
||||
<include domain="sharedpref" path="include_shared_pref1.xml"/>
|
||||
<include domain="database" path="db_name/file_to_include"/>
|
||||
<exclude domain="database" path="db_name/include_folder/file_to_exclude"/>
|
||||
<include domain="external" path="file_to_include"/>
|
||||
<exclude domain="external" path="file_to_exclude"/>
|
||||
<include domain="root" path="file_to_include"/>
|
||||
<exclude domain="root" path="file_to_exclude"/>
|
||||
-->
|
||||
</cloud-backup>
|
||||
<!--
|
||||
<device-transfer>
|
||||
<include .../>
|
||||
<exclude .../>
|
||||
</device-transfer>
|
||||
-->
|
||||
</data-extraction-rules>
|
@ -6,7 +6,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:7.0.4")
|
||||
classpath("com.android.tools.build:gradle:7.1.2")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31")
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
@ -7,7 +7,7 @@ https://github.com/FredHappyface/Android.EweSticker/issues/34
|
||||
<li>“video/3gpp”, “video/mp4”, “video/x-matroska”, “video/webm”</li>
|
||||
</ul></li>
|
||||
<li>Reformat</li>
|
||||
<li>Update deps</li>
|
||||
<li>Update dependencies</li>
|
||||
<li>Limit sticker pack size to resolve <code>java.lang.OutOfMemoryError:
|
||||
at androidx.gridlayout.widget.GridLayout</code></li>
|
||||
</ul>
|
||||
|
Loading…
x
Reference in New Issue
Block a user