Long press on a sticker to show a preview + Update fonts

This commit is contained in:
Kieran BW 2021-10-29 20:18:54 +01:00
parent a20cb26360
commit df71ab1254
13 changed files with 89 additions and 66 deletions

View File

@ -7,12 +7,14 @@ patch-level version changes can be found in [commit messages](../../commits/mast
- Use coil https://coil-kt.github.io/coil/ for supported image types to improve performance - Use coil https://coil-kt.github.io/coil/ for supported image types to improve performance
- Add support for vertical scroll https://github.com/FredHappyface/Android.EweSticker/issues/8 - Add support for vertical scroll https://github.com/FredHappyface/Android.EweSticker/issues/8
- Add Spanish translation https://github.com/FredHappyface/Android.EweSticker/pull/13 - Add Spanish translation https://github.com/FredHappyface/Android.EweSticker/pull/13
- Long press on a sticker to show a preview https://github.com/FredHappyface/Android.EweSticker/issues/10
- Use JavaVersion.VERSION_11 in place of JavaVersion.VERSION_1_8 - Use JavaVersion.VERSION_11 in place of JavaVersion.VERSION_1_8
- Use GridLayout in place of linear views - Use GridLayout in place of linear views
- Refactor and code clean up (reduced ImageKeyboard.kt by about 17% sloc, reduced MainActivity.kt by about 18% sloc) - Refactor and code clean up (reduced ImageKeyboard.kt by about 17% sloc, reduced MainActivity.kt by about 18% sloc)
- Update UI (now more material you inspired) - Update UI (now more material you inspired)
- Update screenshots - Update screenshots
- Update tutorial - Update tutorial
- Update fonts (using fira sans ttf)
## 20211011 - 2021/10/11 ## 20211011 - 2021/10/11

View File

@ -47,6 +47,7 @@ Sticker-board for android inspired by uSticker (forked from woosticker).
- Vertical and Horizontal scrolling - Vertical and Horizontal scrolling
- Change number of rows and sticker preview size - Change number of rows and sticker preview size
- Ties in with the system theme - Ties in with the system theme
- Long press on a sticker to show a preview
## Screenshots ## Screenshots

View File

@ -12,6 +12,7 @@ import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.RelativeLayout
import android.widget.Toast import android.widget.Toast
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
@ -29,6 +30,7 @@ import java.io.FileOutputStream
import java.io.IOException import java.io.IOException
import java.util.* import java.util.*
import kotlin.collections.HashMap import kotlin.collections.HashMap
import kotlin.math.min
/** /**
* ImageKeyboard class inherits from the InputMethodService class - provides the keyboard functionality * ImageKeyboard class inherits from the InputMethodService class - provides the keyboard functionality
@ -42,17 +44,19 @@ class ImageKeyboard : InputMethodService() {
// shared pref // shared pref
private lateinit var mSharedPreferences: SharedPreferences private lateinit var mSharedPreferences: SharedPreferences
private var mVertical = false private var mVertical = false
private var mKeyboardHeight = 0
private var mIconsPerColumn = 0 private var mIconsPerColumn = 0
private var mIconSize = 0 private var mIconSize = 0
private var mFullIconSize = 0
private var mCompatCache = Cache() private var mCompatCache = Cache()
private var mRecentCache = Cache() private var mRecentCache = Cache()
// Attributes // Attributes
private lateinit var mLoadedPacks: HashMap<String, StickerPack> private lateinit var mLoadedPacks: HashMap<String, StickerPack>
private lateinit var mSupportedMimes: MutableMap<String, String> private lateinit var mSupportedMimes: List<String>
// keyboard root view, pack content view, pack list view // keyboard root view, pack content view, pack list view
private lateinit var mKeyboardRoot: View private lateinit var mKeyboardRoot: ViewGroup
private lateinit var mPackContent: ViewGroup private lateinit var mPackContent: ViewGroup
private lateinit var mPacksList: ViewGroup private lateinit var mPacksList: ViewGroup
@ -122,11 +126,13 @@ class ImageKeyboard : InputMethodService() {
mKeyboardRoot = keyboardLayout.findViewById(R.id.keyboardRoot) mKeyboardRoot = keyboardLayout.findViewById(R.id.keyboardRoot)
mPacksList = keyboardLayout.findViewById(R.id.packsList) mPacksList = keyboardLayout.findViewById(R.id.packsList)
mPackContent = keyboardLayout.findViewById(R.id.packContent) mPackContent = keyboardLayout.findViewById(R.id.packContent)
mPackContent.layoutParams?.height = if (mVertical) { mKeyboardHeight = if (mVertical) {
800 800
} else { } else {
mIconSize * mIconsPerColumn + mTotalIconPadding mIconSize * mIconsPerColumn + mTotalIconPadding
} }
mPackContent.layoutParams?.height = mKeyboardHeight
mFullIconSize = (min(resources.displayMetrics.widthPixels, mKeyboardHeight) * 0.8).toInt()
createPackIcons() createPackIcons()
return keyboardLayout return keyboardLayout
} }
@ -147,14 +153,7 @@ class ImageKeyboard : InputMethodService() {
* @param restarting * @param restarting
*/ */
override fun onStartInput(info: EditorInfo?, restarting: Boolean) { override fun onStartInput(info: EditorInfo?, restarting: Boolean) {
mSupportedMimes = Utils.getSupportedMimes() mSupportedMimes = Utils.getSupportedMimes().filter { isCommitContentSupported(info, it) }
val mimesToCheck = mSupportedMimes.keys.toTypedArray()
for (mimeToCheck in mimesToCheck) {
val mimeSupported = isCommitContentSupported(info, mSupportedMimes[mimeToCheck])
if (!mimeSupported) {
mSupportedMimes.remove(mimeToCheck)
}
}
} }
/** /**
@ -178,11 +177,10 @@ class ImageKeyboard : InputMethodService() {
*/ */
private fun doFallbackCommitContent(file: File) { private fun doFallbackCommitContent(file: File) {
// PNG might not be supported // PNG might not be supported
if (mSupportedMimes[".png"] == null) { if ("image/png" !in mSupportedMimes) {
Toast.makeText( Toast.makeText(
applicationContext, applicationContext,
Utils.getFileExtension(file.name) + file.extension + " not supported here.", Toast.LENGTH_SHORT
" not supported here.", Toast.LENGTH_SHORT
).show() ).show()
return return
} }
@ -307,16 +305,38 @@ class ImageKeyboard : InputMethodService() {
imgButton.layoutParams.width = mIconSize imgButton.layoutParams.width = mIconSize
imgButton.load(sticker) imgButton.load(sticker)
imgButton.tag = sticker imgButton.tag = sticker
imgButton.setOnClickListener { view: View -> imgButton.setOnClickListener {
val file = view.tag as File val file = it.tag as File
mRecentCache.add(file.absolutePath) mRecentCache.add(file.absolutePath)
val stickerType = mSupportedMimes[Utils.getFileExtension(file.name)] val stickerType = Utils.getMimeType(file)
if (stickerType == null) { if (stickerType == null || stickerType !in mSupportedMimes) {
doFallbackCommitContent(file) doFallbackCommitContent(file)
return@setOnClickListener return@setOnClickListener
} }
doCommitContent(stickerType, file) doCommitContent(stickerType, file)
} }
imgButton.setOnLongClickListener { view: View ->
val file = view.tag as File
val fullSticker = layoutInflater.inflate(
R.layout.sticker_preview,
mKeyboardRoot,
false
) as RelativeLayout
val fSticker = fullSticker.findViewById<ImageButton>(R.id.stickerButton)
// Set dimens + load image
fullSticker.layoutParams.height =
mKeyboardHeight + (resources.getDimension(R.dimen.pack_dimens) + resources.getDimension(
R.dimen.pack_padding_vertical
) * 2).toInt()
fSticker.layoutParams.height = mFullIconSize
fSticker.layoutParams.width = mFullIconSize
fSticker.load(file)
// Tap to exit popup
fullSticker.setOnClickListener { mKeyboardRoot.removeView(it) }
fSticker.setOnClickListener { mKeyboardRoot.removeView(fullSticker) }
mKeyboardRoot.addView(fullSticker)
return@setOnLongClickListener true
}
pack.addView(imageCard) pack.addView(imageCard)
} }
return packContainer return packContainer

View File

@ -120,9 +120,7 @@ class MainActivity : AppCompatActivity() {
* @return 1 if sticker imported successfully else 0 * @return 1 if sticker imported successfully else 0
*/ */
private fun importSticker(sticker: DocumentFile, pack: String): Int { private fun importSticker(sticker: DocumentFile, pack: String): Int {
if (sticker.isDirectory || if (sticker.isDirectory || sticker.type !in mSupportedMimes) {
!mSupportedMimes.keys.contains(Utils.getFileExtension(sticker.name))
) {
return 0 return 0
} }
val destSticker = File(filesDir, "stickers/" + pack + sticker.name) val destSticker = File(filesDir, "stickers/" + pack + sticker.name)
@ -255,6 +253,4 @@ class MainActivity : AppCompatActivity() {
Snackbar.LENGTH_SHORT Snackbar.LENGTH_SHORT
).show() ).show()
} }
} }

View File

@ -1,52 +1,28 @@
package com.fredhappyface.ewesticker package com.fredhappyface.ewesticker
import android.webkit.MimeTypeMap
import java.io.File
/** /**
* Class to provide utils that are shared across ewesticker. * Class to provide utils that are shared across ewesticker.
*/ */
object Utils { object Utils {
/** /**
* @param name the File's name. Takes in a string here instead of a File because in certain * Get the mimetype of a File
* places we have to use DocumentFile instead-- String name can be found by calling *
* .getName() on both, but they are different classes. * @param file File file to get the mimetype of
* @return returns "." inclusive file extension. * @return String? Return the mimetype or none if it cannot be determined
*/ */
fun getFileExtension(name: String?): String { fun getMimeType(file: File): String? {
if (name == null) { return MimeTypeMap.getSingleton().getMimeTypeFromExtension(file.extension)
return ""
}
val lastIndexOf = name.lastIndexOf(".")
return if (lastIndexOf == -1) {
""
} else name.substring(lastIndexOf)
} }
/** /**
* Needs to create a new HashMap on every call because shallow copies will cause issues between * Return a MutableList of EweSticker Supported mimetypes
* different input areas that support different media types.
* *
* @return HashMap of ewesticker-supported mimes. Keys are "." inclusive. * @return MutableList of EweSticker Supported mimetypes
*/ */
fun getSupportedMimes(): MutableMap<String, String> { fun getSupportedMimes(): MutableList<String> {
val mimes = mutableMapOf( return mutableListOf("image/gif", "image/png", "image/webp", "image/jpeg", "image/heif")
".gif" to "image/gif",
".png" to "image/png",
".webp" to "image/webp",
)
for (el in listOf(".jpg", ".jpeg", ".jpe", ".jif", ".jfif", ".jfi")) {
mimes[el] = "image/jpg"
}
for (el in listOf(
".heif",
".heifs",
".heic",
".heics",
".avci",
".avcs",
".avif",
".avifs"
)) {
mimes[el] = "image/heif"
}
return mimes
} }
} }

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/packContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/bg">
<ImageButton
android:layout_centerInParent="true"
android:id="@+id/stickerButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|center_horizontal|center_vertical"
android:background="@color/sticker"
android:contentDescription="@string/sticker_icon"
android:cropToPadding="true"
android:scaleType="fitCenter" />
<TextView
style="@style/body_text"
android:layout_centerHorizontal="true"
android:text="@string/close_sticker_preview" />
</RelativeLayout>

View File

@ -2,6 +2,7 @@
<!-- App info --> <!-- App info -->
<string name="pack_icon">Icono del paquete</string> <string name="pack_icon">Icono del paquete</string>
<string name="sticker_icon">Icono del sticker</string> <string name="sticker_icon">Icono del sticker</string>
<string name="close_sticker_preview">[Toque para cerrar la vista previa de la etiqueta]</string>
<!-- Update Sticker Pack --> <!-- Update Sticker Pack -->
<string name="update_sticker_pack_heading">Paquete de etiqueta actualización</string> <string name="update_sticker_pack_heading">Paquete de etiqueta actualización</string>
<string name="update_sticker_pack_button">Elija el directorio de fuente de la etiqueta</string> <string name="update_sticker_pack_button">Elija el directorio de fuente de la etiqueta</string>
@ -21,11 +22,12 @@
<!-- Features --> <!-- Features -->
<string name="features_heading">Características</string> <string name="features_heading">Características</string>
<string name="features_text">"- Amplia gama de pegatinas personalizadas admitidas <string name="features_text">"- Amplia gama de pegatinas personalizadas admitidas
- Los formatos admitidos son image/gif (.gif), image/png (.png), image/webp (.webp), image/jpg (.jpg, .jpeg, .jpe, ...), image/heif (.heif,.heifs, .heic, ...) - Los formatos admitidos son image/gif (.gif), image/png (.png), image/webp (.webp), image/jpg (.jpg, .jpeg, .jpe, …), image/heif (.heif,.heifs, .heic, …)
- Envíe stickers en las aplicaciones compatibles (.png se utiliza como alternativa) - Envíe stickers en las aplicaciones compatibles (.png se utiliza como alternativa)
- Desplazamiento vertical y horizontal. - Desplazamiento vertical y horizontal.
- Cambio Número de filas y tamaño de vista previa de la etiqueta - Cambio Número de filas y tamaño de vista previa de la etiqueta
- Se ajusta al tema del sistema.</string> - Se ajusta al tema del sistema.
- Pulse larga en una etiqueta para mostrar una vista previa.</string>
<!-- How to use --> <!-- How to use -->
<string name="how_to_use_heading">Cómo utilizar</string> <string name="how_to_use_heading">Cómo utilizar</string>
<string name="how_to_use_text">Selecciona un directorio que contenga pegatinas y envíalas en tus aplicaciones favoritas.</string> <string name="how_to_use_text">Selecciona un directorio que contenga pegatinas y envíalas en tus aplicaciones favoritas.</string>

View File

@ -3,6 +3,7 @@
<string name="app_name" translatable="false">EweSticker</string> <string name="app_name" translatable="false">EweSticker</string>
<string name="pack_icon">Pack icon</string> <string name="pack_icon">Pack icon</string>
<string name="sticker_icon">Sticker icon</string> <string name="sticker_icon">Sticker icon</string>
<string name="close_sticker_preview">[tap to close sticker preview]</string>
<!-- Update Sticker Pack --> <!-- Update Sticker Pack -->
<string name="update_sticker_pack_heading">Update Sticker Pack</string> <string name="update_sticker_pack_heading">Update Sticker Pack</string>
<string name="update_sticker_pack_button">Choose sticker source directory</string> <string name="update_sticker_pack_button">Choose sticker source directory</string>
@ -26,7 +27,8 @@
- Send stickers in supported apps (.png is used as a fallback) - Send stickers in supported apps (.png is used as a fallback)
- Vertical and Horizontal scrolling - Vertical and Horizontal scrolling
- Change number of rows and sticker preview size - Change number of rows and sticker preview size
- Ties in with the system theme</string> - Ties in with the system theme
- Long press on a sticker to show a preview</string>
<!-- How to use --> <!-- How to use -->
<string name="how_to_use_heading">How to Use</string> <string name="how_to_use_heading">How to Use</string>
<string name="how_to_use_text">Select a directory containing stickers and send them in your favourite apps!</string> <string name="how_to_use_text">Select a directory containing stickers and send them in your favourite apps!</string>

View File

@ -16,7 +16,7 @@
<item name="actionOverflowButtonStyle">@style/OverflowButtonStyle</item> <item name="actionOverflowButtonStyle">@style/OverflowButtonStyle</item>
<item name="actionBarStyle">@style/AppBarBackground</item> <item name="actionBarStyle">@style/AppBarBackground</item>
<item name="actionBarTheme">@style/AppBarText</item> <item name="actionBarTheme">@style/AppBarText</item>
<item name="android:fontFamily">@font/firasans_nf_bold</item> <item name="android:fontFamily">@font/firasans_bold</item>
<item name="colorSurface">@color/sticker</item> <item name="colorSurface">@color/sticker</item>
<item name="colorOnSurface">@color/fg</item> <item name="colorOnSurface">@color/fg</item>
<item name="shapeAppearanceMediumComponent">@style/ShapeAppearance.App.MediumComponent <item name="shapeAppearanceMediumComponent">@style/ShapeAppearance.App.MediumComponent
@ -33,7 +33,7 @@
<style name="Widget.App.Snackbar.TextView" parent="Widget.MaterialComponents.Snackbar.TextView"> <style name="Widget.App.Snackbar.TextView" parent="Widget.MaterialComponents.Snackbar.TextView">
<item name="android:textColor">@color/onAccent</item> <item name="android:textColor">@color/onAccent</item>
<item name="android:textSize">@dimen/text_size_body</item> <item name="android:textSize">@dimen/text_size_body</item>
<item name="android:fontFamily">@font/firasans_nf</item> <item name="android:fontFamily">@font/firasans</item>
</style> </style>
<style name="ThemeOverlay.App.Snackbar" parent=""> <style name="ThemeOverlay.App.Snackbar" parent="">
@ -78,7 +78,8 @@
</style> </style>
<style name="body_text" parent="widget"> <style name="body_text" parent="widget">
<item name="android:fontFamily">@font/firasans_nf</item> <item name="android:textColor">@color/fg</item>
<item name="android:fontFamily">@font/firasans</item>
<item name="android:textSize">@dimen/text_size_body</item> <item name="android:textSize">@dimen/text_size_body</item>
<item name="android:layout_width">wrap_content</item> <item name="android:layout_width">wrap_content</item>
</style> </style>