Long press on a sticker to show a preview + Update fonts
This commit is contained in:
parent
a20cb26360
commit
df71ab1254
@ -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
|
||||
- Add support for vertical scroll https://github.com/FredHappyface/Android.EweSticker/issues/8
|
||||
- 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 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)
|
||||
- Update UI (now more material you inspired)
|
||||
- Update screenshots
|
||||
- Update tutorial
|
||||
- Update fonts (using fira sans ttf)
|
||||
|
||||
## 20211011 - 2021/10/11
|
||||
|
||||
|
@ -47,6 +47,7 @@ Sticker-board for android inspired by uSticker (forked from woosticker).
|
||||
- Vertical and Horizontal scrolling
|
||||
- Change number of rows and sticker preview size
|
||||
- Ties in with the system theme
|
||||
- Long press on a sticker to show a preview
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
@ -12,6 +12,7 @@ import android.view.inputmethod.EditorInfo
|
||||
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.content.res.ResourcesCompat
|
||||
@ -29,6 +30,7 @@ import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import kotlin.collections.HashMap
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* ImageKeyboard class inherits from the InputMethodService class - provides the keyboard functionality
|
||||
@ -42,17 +44,19 @@ class ImageKeyboard : InputMethodService() {
|
||||
// shared pref
|
||||
private lateinit var mSharedPreferences: SharedPreferences
|
||||
private var mVertical = false
|
||||
private var mKeyboardHeight = 0
|
||||
private var mIconsPerColumn = 0
|
||||
private var mIconSize = 0
|
||||
private var mFullIconSize = 0
|
||||
private var mCompatCache = Cache()
|
||||
private var mRecentCache = Cache()
|
||||
|
||||
// Attributes
|
||||
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
|
||||
private lateinit var mKeyboardRoot: View
|
||||
private lateinit var mKeyboardRoot: ViewGroup
|
||||
private lateinit var mPackContent: ViewGroup
|
||||
private lateinit var mPacksList: ViewGroup
|
||||
|
||||
@ -122,11 +126,13 @@ class ImageKeyboard : InputMethodService() {
|
||||
mKeyboardRoot = keyboardLayout.findViewById(R.id.keyboardRoot)
|
||||
mPacksList = keyboardLayout.findViewById(R.id.packsList)
|
||||
mPackContent = keyboardLayout.findViewById(R.id.packContent)
|
||||
mPackContent.layoutParams?.height = if (mVertical) {
|
||||
mKeyboardHeight = if (mVertical) {
|
||||
800
|
||||
} else {
|
||||
mIconSize * mIconsPerColumn + mTotalIconPadding
|
||||
}
|
||||
mPackContent.layoutParams?.height = mKeyboardHeight
|
||||
mFullIconSize = (min(resources.displayMetrics.widthPixels, mKeyboardHeight) * 0.8).toInt()
|
||||
createPackIcons()
|
||||
return keyboardLayout
|
||||
}
|
||||
@ -147,14 +153,7 @@ class ImageKeyboard : InputMethodService() {
|
||||
* @param restarting
|
||||
*/
|
||||
override fun onStartInput(info: EditorInfo?, restarting: Boolean) {
|
||||
mSupportedMimes = Utils.getSupportedMimes()
|
||||
val mimesToCheck = mSupportedMimes.keys.toTypedArray()
|
||||
for (mimeToCheck in mimesToCheck) {
|
||||
val mimeSupported = isCommitContentSupported(info, mSupportedMimes[mimeToCheck])
|
||||
if (!mimeSupported) {
|
||||
mSupportedMimes.remove(mimeToCheck)
|
||||
}
|
||||
}
|
||||
mSupportedMimes = Utils.getSupportedMimes().filter { isCommitContentSupported(info, it) }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,11 +177,10 @@ class ImageKeyboard : InputMethodService() {
|
||||
*/
|
||||
private fun doFallbackCommitContent(file: File) {
|
||||
// PNG might not be supported
|
||||
if (mSupportedMimes[".png"] == null) {
|
||||
if ("image/png" !in mSupportedMimes) {
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
Utils.getFileExtension(file.name) +
|
||||
" not supported here.", Toast.LENGTH_SHORT
|
||||
file.extension + " not supported here.", Toast.LENGTH_SHORT
|
||||
).show()
|
||||
return
|
||||
}
|
||||
@ -307,16 +305,38 @@ class ImageKeyboard : InputMethodService() {
|
||||
imgButton.layoutParams.width = mIconSize
|
||||
imgButton.load(sticker)
|
||||
imgButton.tag = sticker
|
||||
imgButton.setOnClickListener { view: View ->
|
||||
val file = view.tag as File
|
||||
imgButton.setOnClickListener {
|
||||
val file = it.tag as File
|
||||
mRecentCache.add(file.absolutePath)
|
||||
val stickerType = mSupportedMimes[Utils.getFileExtension(file.name)]
|
||||
if (stickerType == null) {
|
||||
val stickerType = Utils.getMimeType(file)
|
||||
if (stickerType == null || stickerType !in mSupportedMimes) {
|
||||
doFallbackCommitContent(file)
|
||||
return@setOnClickListener
|
||||
}
|
||||
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)
|
||||
}
|
||||
return packContainer
|
||||
|
@ -120,9 +120,7 @@ class MainActivity : AppCompatActivity() {
|
||||
* @return 1 if sticker imported successfully else 0
|
||||
*/
|
||||
private fun importSticker(sticker: DocumentFile, pack: String): Int {
|
||||
if (sticker.isDirectory ||
|
||||
!mSupportedMimes.keys.contains(Utils.getFileExtension(sticker.name))
|
||||
) {
|
||||
if (sticker.isDirectory || sticker.type !in mSupportedMimes) {
|
||||
return 0
|
||||
}
|
||||
val destSticker = File(filesDir, "stickers/" + pack + sticker.name)
|
||||
@ -255,6 +253,4 @@ class MainActivity : AppCompatActivity() {
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,52 +1,28 @@
|
||||
package com.fredhappyface.ewesticker
|
||||
|
||||
import android.webkit.MimeTypeMap
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Class to provide utils that are shared across ewesticker.
|
||||
*/
|
||||
object Utils {
|
||||
/**
|
||||
* @param name the File's name. Takes in a string here instead of a File because in certain
|
||||
* places we have to use DocumentFile instead-- String name can be found by calling
|
||||
* .getName() on both, but they are different classes.
|
||||
* @return returns "." inclusive file extension.
|
||||
* Get the mimetype of a File
|
||||
*
|
||||
* @param file File file to get the mimetype of
|
||||
* @return String? Return the mimetype or none if it cannot be determined
|
||||
*/
|
||||
fun getFileExtension(name: String?): String {
|
||||
if (name == null) {
|
||||
return ""
|
||||
}
|
||||
val lastIndexOf = name.lastIndexOf(".")
|
||||
return if (lastIndexOf == -1) {
|
||||
""
|
||||
} else name.substring(lastIndexOf)
|
||||
fun getMimeType(file: File): String? {
|
||||
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(file.extension)
|
||||
}
|
||||
|
||||
/**
|
||||
* Needs to create a new HashMap on every call because shallow copies will cause issues between
|
||||
* different input areas that support different media types.
|
||||
* Return a MutableList of EweSticker Supported mimetypes
|
||||
*
|
||||
* @return HashMap of ewesticker-supported mimes. Keys are "." inclusive.
|
||||
* @return MutableList of EweSticker Supported mimetypes
|
||||
*/
|
||||
fun getSupportedMimes(): MutableMap<String, String> {
|
||||
val mimes = mutableMapOf(
|
||||
".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
|
||||
fun getSupportedMimes(): MutableList<String> {
|
||||
return mutableListOf("image/gif", "image/png", "image/webp", "image/jpeg", "image/heif")
|
||||
}
|
||||
}
|
||||
|
BIN
app/src/main/res/font/firasans.ttf
Normal file
BIN
app/src/main/res/font/firasans.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/firasans_bold.ttf
Normal file
BIN
app/src/main/res/font/firasans_bold.ttf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
23
app/src/main/res/layout/sticker_preview.xml
Normal file
23
app/src/main/res/layout/sticker_preview.xml
Normal 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>
|
@ -2,6 +2,7 @@
|
||||
<!-- App info -->
|
||||
<string name="pack_icon">Icono del paquete</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 -->
|
||||
<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>
|
||||
@ -21,11 +22,12 @@
|
||||
<!-- Features -->
|
||||
<string name="features_heading">Características</string>
|
||||
<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)
|
||||
- Desplazamiento vertical y horizontal.
|
||||
- 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 -->
|
||||
<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>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<string name="app_name" translatable="false">EweSticker</string>
|
||||
<string name="pack_icon">Pack icon</string>
|
||||
<string name="sticker_icon">Sticker icon</string>
|
||||
<string name="close_sticker_preview">[tap to close sticker preview]</string>
|
||||
<!-- Update Sticker Pack -->
|
||||
<string name="update_sticker_pack_heading">Update Sticker Pack</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)
|
||||
- Vertical and Horizontal scrolling
|
||||
- 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 -->
|
||||
<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>
|
||||
|
@ -16,7 +16,7 @@
|
||||
<item name="actionOverflowButtonStyle">@style/OverflowButtonStyle</item>
|
||||
<item name="actionBarStyle">@style/AppBarBackground</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="colorOnSurface">@color/fg</item>
|
||||
<item name="shapeAppearanceMediumComponent">@style/ShapeAppearance.App.MediumComponent
|
||||
@ -33,7 +33,7 @@
|
||||
<style name="Widget.App.Snackbar.TextView" parent="Widget.MaterialComponents.Snackbar.TextView">
|
||||
<item name="android:textColor">@color/onAccent</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 name="ThemeOverlay.App.Snackbar" parent="">
|
||||
@ -78,7 +78,8 @@
|
||||
</style>
|
||||
|
||||
<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:layout_width">wrap_content</item>
|
||||
</style>
|
||||
|
Loading…
x
Reference in New Issue
Block a user