add logging
This commit is contained in:
parent
16ee306864
commit
eea1b0d2f5
@ -31,7 +31,6 @@ tasks.register("genDocs") {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
android {
|
||||
compileSdk = 35
|
||||
buildToolsVersion = "35.0.0"
|
||||
@ -84,6 +83,7 @@ dependencies {
|
||||
implementation("io.coil-kt:coil-svg:2.7.0")
|
||||
implementation("androidx.gridlayout:gridlayout:1.0.0")
|
||||
implementation("io.noties.markwon:core:4.6.2")
|
||||
implementation("com.elvishew:xlog:1.11.1")
|
||||
androidTestImplementation("junit:junit:4.13.2")
|
||||
androidTestImplementation("androidx.test:core:1.6.1")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.2.1")
|
||||
|
@ -28,6 +28,7 @@ import coil.decode.SvgDecoder
|
||||
import coil.decode.VideoFrameDecoder
|
||||
import coil.imageLoader
|
||||
import coil.load
|
||||
import com.elvishew.xlog.XLog
|
||||
import com.fredhappyface.ewesticker.adapter.StickerPackAdapter
|
||||
import com.fredhappyface.ewesticker.model.StickerPack
|
||||
import com.fredhappyface.ewesticker.utilities.Cache
|
||||
@ -94,6 +95,10 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
|
||||
override fun onCreate() {
|
||||
// Misc
|
||||
super.onCreate()
|
||||
|
||||
XLog.i("=".repeat(80))
|
||||
XLog.i("Loaded $packageName:${javaClass.name}")
|
||||
|
||||
val scale = baseContext.resources.displayMetrics.density
|
||||
// Setup coil
|
||||
val imageLoader =
|
||||
@ -113,6 +118,10 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
|
||||
this.sharedPreferences = PreferenceManager.getDefaultSharedPreferences(baseContext)
|
||||
this.backupSharedPreferences =
|
||||
this.getSharedPreferences("backup_prefs", Context.MODE_PRIVATE)
|
||||
|
||||
XLog.i("Loading private shared preferences: ${this.sharedPreferences.all}")
|
||||
XLog.i("Loading backup shared preferences: ${this.backupSharedPreferences.all}")
|
||||
|
||||
this.restoreOnClose = this.backupSharedPreferences.getBoolean("restoreOnClose", false)
|
||||
this.vertical = this.backupSharedPreferences.getBoolean("vertical", false)
|
||||
this.scroll = this.backupSharedPreferences.getBoolean("scroll", false)
|
||||
@ -147,6 +156,8 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
|
||||
}
|
||||
this.allStickers += pack.stickerList
|
||||
}
|
||||
|
||||
XLog.i("Loaded all packs: [${this.loadedPacks.keys.joinToString(", ")}]")
|
||||
this.activePack = this.sharedPreferences.getString("activePack", "").toString()
|
||||
// Caches
|
||||
this.sharedPreferences.getString("recentCache", "")?.let {
|
||||
@ -222,6 +233,7 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
|
||||
|
||||
/** When leaving some input field update the caches */
|
||||
override fun onFinishInput() {
|
||||
XLog.i("Updating sharedPreferences based on use, and closing...")
|
||||
val editor = this.sharedPreferences.edit()
|
||||
editor.putString("recentCache", this.recentCache.toSharedPref())
|
||||
editor.putString("compatCache", this.compatCache.toSharedPref())
|
||||
@ -240,6 +252,7 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
|
||||
* @param packName String
|
||||
*/
|
||||
private fun switchPackLayout(packName: String) {
|
||||
XLog.i("Switching pack to '$packName'")
|
||||
this.activePack = packName
|
||||
for (packCard in this.packsList) {
|
||||
val packButton = packCard.findViewById<ImageButton>(R.id.stickerButton)
|
||||
@ -280,6 +293,7 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
|
||||
* Set the current tab to the search page/ view
|
||||
*/
|
||||
private fun searchView() {
|
||||
XLog.i("Switching to search")
|
||||
for (packCard in this.packsList) {
|
||||
val packButton = packCard.findViewById<ImageButton>(R.id.stickerButton)
|
||||
if (packButton.tag == "__search__") {
|
||||
@ -454,9 +468,6 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
|
||||
this.loadedPacks.keys.sorted()
|
||||
}.toTypedArray()
|
||||
|
||||
|
||||
|
||||
|
||||
for (sortedPackName in sortedPackNames) {
|
||||
val packButton = addPackButton(sortedPackName)
|
||||
packButton.load(this.loadedPacks[sortedPackName]?.thumbSticker)
|
||||
|
@ -17,12 +17,20 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.elvishew.xlog.LogConfiguration
|
||||
import com.elvishew.xlog.LogLevel
|
||||
import com.elvishew.xlog.XLog
|
||||
import com.elvishew.xlog.printer.AndroidPrinter
|
||||
import com.elvishew.xlog.printer.file.FilePrinter
|
||||
import com.elvishew.xlog.printer.file.clean.FileLastModifiedCleanStrategy
|
||||
import com.fredhappyface.ewesticker.utilities.StickerImporter
|
||||
import com.fredhappyface.ewesticker.utilities.Toaster
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import io.noties.markwon.Markwon
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.util.Calendar
|
||||
|
||||
/** MainActivity class inherits from the AppCompatActivity class - provides the settings view */
|
||||
@ -43,6 +51,17 @@ class MainActivity : AppCompatActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
val logConfig = LogConfiguration.Builder().logLevel(LogLevel.ALL).tag("EweSticker").build()
|
||||
val androidPrinter =
|
||||
AndroidPrinter(true) // Printer that print the log using android.util.Log
|
||||
val filePrinter = FilePrinter.Builder(
|
||||
File(filesDir, "logs").path
|
||||
).cleanStrategy(FileLastModifiedCleanStrategy(86_400_000)).build() // 1day
|
||||
XLog.init(logConfig, androidPrinter, filePrinter)
|
||||
|
||||
XLog.i("=".repeat(80))
|
||||
XLog.i("Loaded $packageName:$localClassName")
|
||||
|
||||
val markwon: Markwon = Markwon.create(this)
|
||||
val featuresText = findViewById<TextView>(R.id.features_text)
|
||||
markwon.setMarkdown(featuresText, getString(R.string.features_text))
|
||||
@ -54,6 +73,9 @@ class MainActivity : AppCompatActivity() {
|
||||
this.sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
this.backupSharedPreferences =
|
||||
this.getSharedPreferences("backup_prefs", Context.MODE_PRIVATE)
|
||||
|
||||
XLog.i("Loading private shared preferences: ${this.sharedPreferences.all}")
|
||||
XLog.i("Loading backup shared preferences: ${this.backupSharedPreferences.all}")
|
||||
this.contextView = findViewById(R.id.activityMainRoot)
|
||||
this.toaster = Toaster(baseContext)
|
||||
refreshStickerDirPath()
|
||||
@ -71,12 +93,16 @@ class MainActivity : AppCompatActivity() {
|
||||
toggle(findViewById(R.id.insensitive_sort), "insensitiveSort", false) {}
|
||||
|
||||
val versionText: TextView = findViewById(R.id.versionText)
|
||||
var version = getString(R.string.version_text)
|
||||
try {
|
||||
val packageInfo = packageManager.getPackageInfo(packageName, 0)
|
||||
versionText.text = packageInfo.versionName
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
versionText.text = getString(R.string.version_text)
|
||||
version = packageInfo.versionName ?: version
|
||||
} catch (_: PackageManager.NameNotFoundException) {
|
||||
}
|
||||
|
||||
versionText.text = version
|
||||
XLog.i("Version: $version")
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,6 +133,22 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private val saveFileLauncher =
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode == RESULT_OK) {
|
||||
result.data?.data?.also { uri ->
|
||||
val file = File(filesDir, "logs/log")
|
||||
if (file.exists()) {
|
||||
contentResolver.openOutputStream(uri)?.use { outputStream ->
|
||||
file.inputStream().use { inputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on button press to launch settings
|
||||
*
|
||||
@ -129,6 +171,20 @@ class MainActivity : AppCompatActivity() {
|
||||
chooseDirResultLauncher.launch(intent)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on button press to save logs
|
||||
*
|
||||
* @param ignoredView: View
|
||||
*/
|
||||
fun saveLogs(ignoredView: View) {
|
||||
val saveIntent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = "text/plain"
|
||||
putExtra(Intent.EXTRA_TITLE, "ewesticker.log")
|
||||
}
|
||||
saveFileLauncher.launch(saveIntent)
|
||||
}
|
||||
|
||||
/**
|
||||
* reloadStickers
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.fredhappyface.ewesticker
|
||||
package com.fredhappyface.ewesticker.utilities
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
@ -6,8 +6,8 @@ import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.View
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import com.fredhappyface.ewesticker.utilities.Toaster
|
||||
import com.fredhappyface.ewesticker.utilities.Utils
|
||||
import com.elvishew.xlog.XLog
|
||||
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
@ -28,6 +28,7 @@ private const val BUFFER_SIZE = 64 * 1024 // 64 KB
|
||||
* @property context: application baseContext
|
||||
* @property toaster: an instance of Toaster (used to store an error state for later reporting to the
|
||||
* user)
|
||||
* @property progressBar: LinearProgressIndicator that we update as we import stickers
|
||||
*/
|
||||
class StickerImporter(
|
||||
private val context: Context,
|
||||
@ -36,6 +37,7 @@ class StickerImporter(
|
||||
) {
|
||||
private val supportedMimes = Utils.getSupportedMimes()
|
||||
private val packSizes: MutableMap<String, Int> = mutableMapOf()
|
||||
private var detectedStickers = 0
|
||||
private var totalStickers = 0
|
||||
|
||||
private val mainHandler = Handler(Looper.getMainLooper())
|
||||
@ -53,14 +55,17 @@ class StickerImporter(
|
||||
* @param stickerDirPath a URI to the stickers directory to import into EweSticker
|
||||
*/
|
||||
suspend fun importStickers(stickerDirPath: String): Int {
|
||||
XLog.i("Removing old stickers...")
|
||||
File(context.filesDir, "stickers").deleteRecursively()
|
||||
withContext(Dispatchers.Main) {
|
||||
progressBar.visibility = View.VISIBLE
|
||||
progressBar.isIndeterminate = true
|
||||
}
|
||||
|
||||
XLog.i("Walking $stickerDirPath...")
|
||||
val leafNodes = fileWalk(DocumentFile.fromTreeUri(context, Uri.parse(stickerDirPath)))
|
||||
if (leafNodes.size > MAX_FILES) {
|
||||
XLog.w("Found more than $MAX_FILES stickers, notify user")
|
||||
toaster.setState(1)
|
||||
}
|
||||
|
||||
@ -69,6 +74,7 @@ class StickerImporter(
|
||||
}
|
||||
|
||||
// Perform concurrent file copy operations
|
||||
XLog.i("Perform concurrent file copy operations...")
|
||||
withContext(Dispatchers.IO) {
|
||||
leafNodes.take(MAX_FILES).mapIndexed { index, file ->
|
||||
async {
|
||||
@ -84,7 +90,9 @@ class StickerImporter(
|
||||
progressBar.visibility = View.GONE
|
||||
}
|
||||
|
||||
return leafNodes.size
|
||||
XLog.i("Copied $totalStickers / $detectedStickers")
|
||||
|
||||
return totalStickers
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,10 +106,12 @@ class StickerImporter(
|
||||
val parentDir = sticker.parentFile?.name ?: "__default__"
|
||||
val packSize = packSizes[parentDir] ?: 0
|
||||
if (packSize > MAX_PACK_SIZE) {
|
||||
XLog.w("Found more than $MAX_PACK_SIZE stickers in '$parentDir', notify user")
|
||||
toaster.setState(2)
|
||||
return
|
||||
}
|
||||
if (sticker.type !in supportedMimes) {
|
||||
XLog.w("'$parentDir/${sticker.name}' is not a supported mimetype (${sticker.type}), notify user")
|
||||
toaster.setState(3)
|
||||
return
|
||||
}
|
||||
@ -126,7 +136,9 @@ class StickerImporter(
|
||||
}
|
||||
totalStickers++
|
||||
}
|
||||
} catch (_: IOException) {
|
||||
} catch (e: IOException) {
|
||||
XLog.e("There was an IOException when copying '${parentDir}/${sticker.name}'!")
|
||||
XLog.e(e)
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,9 +160,10 @@ class StickerImporter(
|
||||
currentFile?.listFiles()?.forEach { file ->
|
||||
if (file.isFile) {
|
||||
leafNodes.add(file)
|
||||
totalStickers++
|
||||
detectedStickers++
|
||||
|
||||
if (leafNodes.size >= MAX_FILES) {
|
||||
if (leafNodes.size > MAX_FILES + 1) {
|
||||
XLog.w("Found more than ${MAX_FILES + 1} stickers, so returning early")
|
||||
return leafNodes
|
||||
}
|
||||
} else if (file.isDirectory) {
|
@ -4,7 +4,6 @@ import android.content.ClipDescription
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.util.Log
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputConnection
|
||||
import androidx.core.content.FileProvider
|
||||
@ -13,6 +12,7 @@ import androidx.core.view.inputmethod.InputConnectionCompat
|
||||
import androidx.core.view.inputmethod.InputContentInfoCompat
|
||||
import coil.ImageLoader
|
||||
import coil.request.ImageRequest
|
||||
import com.elvishew.xlog.XLog
|
||||
import com.fredhappyface.ewesticker.R
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -50,6 +50,15 @@ class StickerSender(
|
||||
private val supportedMimes = this.currentInputEditorInfo?.contentMimeTypes ?: emptyArray()
|
||||
private val packageName = this.currentInputEditorInfo?.packageName
|
||||
|
||||
init {
|
||||
XLog.i("Connecting to $packageName which supports [${supportedMimes.joinToString(", ")}]")
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function to display a toast message to the user
|
||||
*
|
||||
* @param message String
|
||||
*/
|
||||
private fun showToast(message: String) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
toaster.toast(message)
|
||||
@ -68,6 +77,8 @@ class StickerSender(
|
||||
val compatSticker = File(internalDir, "__compatSticker__/$compatStickerName.png")
|
||||
|
||||
if (!compatSticker.exists()) {
|
||||
XLog.i("Create a fallback png sticker '__compatSticker__/$compatStickerName.png'")
|
||||
|
||||
compatSticker.parentFile?.mkdirs()
|
||||
try {
|
||||
val request = ImageRequest.Builder(context)
|
||||
@ -95,6 +106,11 @@ class StickerSender(
|
||||
return compatSticker
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method to send a sticker to an InputConnectionCompat, this attempts to send via the happy path (assuming the
|
||||
* InputConnectionCompat supports the stickers mime type. Otherwise attempts falling back to png, and then finally if that fails,
|
||||
* opening a share sheet
|
||||
*/
|
||||
fun sendSticker(file: File) {
|
||||
val stickerType = Utils.getMimeType(file) ?: "__unknown__"
|
||||
|
||||
@ -105,63 +121,28 @@ class StickerSender(
|
||||
|| "video/*" in supportedMimes && stickerType.startsWith("video/"))
|
||||
&& stickerType != "image/svg+xml"
|
||||
) {
|
||||
|
||||
if (!doCommitContent(stickerType, file)) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
doFallbackCommitContent(file)
|
||||
doFallbackCommitContent(stickerType, file)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
doFallbackCommitContent(file)
|
||||
doFallbackCommitContent(stickerType, file)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun openShareSheet(file: File) {
|
||||
val uri = FileProvider.getUriForFile(
|
||||
context,
|
||||
"com.fredhappyface.ewesticker.inputcontent",
|
||||
file,
|
||||
)
|
||||
|
||||
val shareIntent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
putExtra(Intent.EXTRA_STREAM, uri)
|
||||
type = "image/*"
|
||||
}
|
||||
|
||||
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
|
||||
val chooserIntent = Intent.createChooser(shareIntent, "Share Sticker")
|
||||
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(chooserIntent)
|
||||
}
|
||||
|
||||
private suspend fun doFallbackCommitContent(file: File) {
|
||||
|
||||
if ("image/png" in supportedMimes || "image/*" in supportedMimes) {
|
||||
val compatSticker = createCompatSticker(file)
|
||||
if (compatSticker != null) {
|
||||
if (!doCommitContent("image/png", compatSticker)) {
|
||||
openShareSheet(file)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
openShareSheet(file)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a sticker file to a InputConnectionCompat
|
||||
* Called by sendSticker. Send a sticker file to a InputConnectionCompat
|
||||
*
|
||||
* @param mimeType String
|
||||
* @param file File
|
||||
* @return success Boolean
|
||||
*/
|
||||
private fun doCommitContent(mimeType: String, file: File): Boolean {
|
||||
// Log.d("QWERTY", "Sending ${file.name} ($mimeType) to ${this.packageName}")
|
||||
XLog.i("Sending ${file.name} ($mimeType) to ${this.packageName}")
|
||||
val inputContentInfoCompat = InputContentInfoCompat(
|
||||
FileProvider.getUriForFile(
|
||||
context,
|
||||
@ -185,4 +166,53 @@ class StickerSender(
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by sendSticker. Otherwise attempts falling back to png, and then finally if that fails, opening a
|
||||
* share sheet to send the sticker
|
||||
*
|
||||
* @param mimeType String
|
||||
* @param file File
|
||||
*/
|
||||
private suspend fun doFallbackCommitContent(mimeType: String, file: File) {
|
||||
|
||||
if ("image/png" in supportedMimes || "image/*" in supportedMimes) {
|
||||
val compatSticker = createCompatSticker(file)
|
||||
if (compatSticker != null) {
|
||||
if (!doCommitContent("image/png", compatSticker)) {
|
||||
openShareSheet(mimeType, file)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
openShareSheet(mimeType, file)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by doFallbackCommitContent. Opens a share sheet to send the sticker
|
||||
*
|
||||
* @param mimeType String
|
||||
* @param file File
|
||||
*/
|
||||
private fun openShareSheet(mimeType: String, file: File) {
|
||||
XLog.i("$packageName reports that is doesn't support png over its InputConnectionCompat, so open a share sheet")
|
||||
val uri = FileProvider.getUriForFile(
|
||||
context,
|
||||
"com.fredhappyface.ewesticker.inputcontent",
|
||||
file,
|
||||
)
|
||||
|
||||
val shareIntent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
putExtra(Intent.EXTRA_STREAM, uri)
|
||||
type = mimeType
|
||||
}
|
||||
|
||||
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
|
||||
val chooserIntent = Intent.createChooser(shareIntent, "Share Sticker")
|
||||
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(chooserIntent)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -405,6 +405,25 @@
|
||||
android:text="@string/version_text" />
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
<!-- Logs -->
|
||||
<com.google.android.material.card.MaterialCardView style="@style/card">
|
||||
|
||||
<LinearLayout
|
||||
style="@style/cardchild"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
style="@style/heading"
|
||||
android:text="@string/logs_heading" />
|
||||
|
||||
<Button
|
||||
style="@style/button"
|
||||
android:onClick="saveLogs"
|
||||
android:text="@string/logs_button"
|
||||
app:shapeAppearance="?attr/shapeAppearanceSmallComponent" />
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
@ -24,7 +24,6 @@
|
||||
android:layout_height="@dimen/qwerty_row_height"
|
||||
android:id="@+id/search_text"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@ -51,8 +50,6 @@
|
||||
android:layout_gravity="center_horizontal"
|
||||
>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@ -63,10 +60,6 @@
|
||||
android:layout_gravity="center_horizontal"
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -8,7 +8,6 @@
|
||||
<dimen name="text_size_tiny">10sp</dimen>
|
||||
<dimen name="qwerty_row_height">40sp</dimen>
|
||||
|
||||
|
||||
<dimen name="content_margin">10dp</dimen>
|
||||
<dimen name="card_margin">16dp</dimen>
|
||||
<dimen name="content_margin_top">8dp</dimen>
|
||||
|
@ -70,7 +70,9 @@ Copyright © Randy Zhou</string>
|
||||
(See the license for more information https://github.com/FredHappyface/Android.EweSticker/blob/main/LICENSE.md )</string>
|
||||
<string name="version_heading">Version Info</string>
|
||||
<string name="version_text" translatable="false">[debug]</string>
|
||||
|
||||
<!-- Logs -->
|
||||
<string name="logs_heading">Logs</string>
|
||||
<string name="logs_button">Get log file</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>
|
||||
|
@ -29,7 +29,6 @@
|
||||
<item name="android:background">@drawable/qwerty_key</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="ToolbarTitleTextAppearance" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Title">
|
||||
<item name="android:textSize">@dimen/text_size_title</item>
|
||||
</style>
|
||||
|
Loading…
x
Reference in New Issue
Block a user