15 Commits

Author SHA1 Message Date
renovate[bot] 9108e465ab Update Gradle to v9.5.1 2026-05-30 11:16:24 +00:00
Michachatz 06962a32ed Merge pull request #2 from Michatec/renovate/configure
Configure Renovate
2026-05-26 00:02:30 +02:00
renovate[bot] 7f5d27f656 Add renovate.json 2026-04-15 21:35:13 +00:00
Michatec 7b561fe428 Merge branch 'master' of https://github.com/Michatec/michas-droid 2026-04-09 14:27:07 +02:00
Michatec 688d03ba8b - Migrate build system to Kotlin DSL (build.gradle.kts, settings.gradle.kts)
- Upgrade `compileSdk` and `targetSdk` to 36
- Add German (`de`) localization and string resources
- Add Michachatz F-Droid repository to default list
- Update dependencies and plugins in `libs.versions.toml`
- Remove manual signing configuration from README.md
- Refactor code to use non-deprecated `alpha` property and context-based string retrieval
- Clean up `buildConfig` and locale filtering logic
2026-04-09 13:34:45 +02:00
Michachatz fb06922278 Remove version badge from README
Removed a version badge from the README.
2026-03-30 00:22:31 +02:00
Michachatz 821d847ce2 Update license link in README.md 2026-03-30 00:22:19 +02:00
Michachatz 5a76773ae3 Enhance README with project badges
Added badges for version, downloads, issues, contributors, and license.
2026-03-29 23:55:39 +02:00
Michachatz f303844e28 Add warning about Google identity requirements
Added a warning about upcoming Google requirements for apps on certified Android devices.
2026-03-25 07:37:58 +01:00
Michatec 9e32fe3871 - Move FreeDroidWarn initialization from MainApplication to ScreenActivity 2026-03-24 17:43:21 +01:00
Michatec 6b2ac6d740 - Removed old changelogs
- Removed launcher SVG and build script
2026-03-24 17:33:47 +01:00
Michatec 2c9af08e8c - Refactor code to use idiomatic Kotlin functions like isNullOrEmpty(), associateBy, and appendRange
- Increase `DiffUtil` threshold in `CursorRecyclerAdapter` to 500 and optimize equality checks
- Simplify locale configuration by removing legacy Android SDK version checks
- Remove unnecessary `@SuppressLint` annotations and `@Volatile` modifiers
- Improve performance of collection operations in `ProductFragment` and `Preferences` using `associateBy` and `firstOrNull`
- Suppress deprecation warnings for `getOpacity` in `DrawableWrapper` and `TabsFragment`
- Clean up service binding logic in `Connection.kt` with better type casting
2026-03-24 17:31:51 +01:00
Michatec bdd204d9de - Migrate dependencies to Version Catalog (libs.versions.toml)
- Update Kotlin to 2.3.20 and Jackson Core to 2.21.2
- Update Gradle Wrapper to 9.4.1
- Bump version code to 17 and version name to 1.7
- Remove unused `percentTranslationY` property from `FragmentLinearLayout`
- Clean up semicolons in `MainApplication.kt`
- Update `.gitignore` to include `gradle-daemon-jvm.properties`
2026-03-24 13:07:06 +01:00
Michachatz 112d4bdb62 Integrate FreeDroidWarn for upgrade warnings 2026-03-24 08:43:37 +01:00
Michachatz ebb54fd19b Add JitPack repository and FreeDroidWarn dependency 2026-03-24 08:25:38 +01:00
34 changed files with 616 additions and 463 deletions
+3 -2
View File
@@ -1,7 +1,7 @@
/*
!/.gitignore
!/build.gradle
!/settings.gradle
!/build.gradle.kts
!/settings.gradle.kts
!/COPYING
!/extra
!/gradle
@@ -12,3 +12,4 @@
!/proguard.pro
!/README.md
!/src
/gradle/gradle-daemon-jvm.properties
+13 -9
View File
@@ -1,9 +1,22 @@
# Michas Droid
<p align="center">
<a href="https://github.com/michatec/michas-droid/releases"><img src="https://img.shields.io/github/downloads/michatec/michas-droid/total.svg?style=flat-square" /></a>
<a href="https://github.com/michatec/michas-droid/issues"><img src="https://img.shields.io/github/issues-raw/michatec/michas-droid.svg?style=flat-square&label=issues" /></a>
<a href="https://github.com/michatec/michas-droid/graphs/contributors"><img src="https://img.shields.io/github/contributors/michatec/michas-droid?style=flat-square" /></a>
<a href="https://github.com/michatec/michas-droid/blob/master/COPYING"><img src="https://img.shields.io/github/license/michatec/michas-droid?style=flat-square" /></a>
</p>
Yet another F-Droid client.
[![Release](https://img.shields.io/github/v/release/michatec/michas-droid)](https://github.com/michatec/michas-droid/releases/latest)
## Warning ⚠️
Google has announced that, starting in 2026/2027, all apps on certified Android devices will require the developer to submit personal identity details directly to Google.
Since the developers of this app do not agree to this requirement, this app will no longer work on certified Android devices after that time.
## Description
Unofficial F-Droid client in the style of the classic one.
@@ -34,15 +47,6 @@ or sharing local repositories nearby.
Specify your Android SDK path either using the `ANDROID_HOME` environment variable, or by filling out the `sdk.dir`
property in `local.properties`.
Signing can be done automatically using `keystore.properties` as follows:
```properties
store.file=/path/to/keystore
store.password=key-store-password
key.alias=key-alias
key.password=key-password
```
Run `./gradlew assembleRelease` to build the package, which can be installed using the Android package manager.
## License
-110
View File
@@ -1,110 +0,0 @@
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:9.1.0'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.3.10'
}
}
apply plugin: 'com.android.application'
android {
namespace 'com.michatec.store'
compileSdk 36
defaultConfig {
applicationId 'com.michatec.store'
minSdk 30
targetSdk 36
versionCode 16
versionName '1.6'
def languages = [ 'en' ]
buildConfigField 'String[]', 'LANGUAGES', '{ "' + languages.join('", "') + '" }'
resConfigs languages
}
buildFeatures {
buildConfig = true
}
sourceSets {
main {
java.srcDirs += 'src/main/kotlin'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
flavorDimensions "distributor"
productFlavors {
michas {
dimension "distributor"
buildConfigField "boolean", "FLAVOR_FDROID", "false"
}
fdroid {
dimension "distributor"
buildConfigField "boolean", "FLAVOR_FDROID", "true"
}
}
buildTypes {
debug {
minifyEnabled false
shrinkResources false
}
release {
minifyEnabled true
shrinkResources false
}
}
def keystorePropertiesFile = rootProject.file('keystore.properties')
if (keystorePropertiesFile.exists()) {
def keystoreProperties = new Properties()
keystoreProperties.load(keystorePropertiesFile.newDataInputStream())
def signing = [
storeFile: keystoreProperties['store.file'],
storePassword: keystoreProperties['store.password'],
keyAlias: keystoreProperties['key.alias'],
keyPassword: keystoreProperties['key.password']
]
if (!signing.any { _, v -> v == null }) {
signingConfigs {
primary {
storeFile file(signing.storeFile)
storePassword signing.storePassword
keyAlias signing.keyAlias
keyPassword signing.keyPassword
enableV2Signing false
}
}
}
}
}
repositories {
google()
mavenCentral()
}
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib:2.3.10'
implementation 'androidx.fragment:fragment-ktx:1.8.9'
implementation 'androidx.viewpager2:viewpager2:1.1.0'
implementation 'androidx.vectordrawable:vectordrawable:1.2.0'
implementation 'com.squareup.okhttp3:okhttp:5.3.2'
implementation 'io.reactivex.rxjava3:rxjava:3.1.12'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.2'
implementation 'com.fasterxml.jackson.core:jackson-core:2.21.1'
implementation 'com.squareup.picasso:picasso:2.71828'
}
+80
View File
@@ -0,0 +1,80 @@
plugins {
alias(libs.plugins.android.application)
}
android {
namespace = "com.michatec.store"
compileSdk = 36
defaultConfig {
applicationId = "com.michatec.store"
minSdk = 30
targetSdk = 36
versionCode = 18
versionName = "1.8"
val languages = listOf("en", "de")
buildConfigField("String[]", "LANGUAGES", "{ \"${languages.joinToString("\", \"")}\" }")
@Suppress("UnstableApiUsage")
androidResources {
localeFilters += languages
}
}
buildFeatures {
buildConfig = true
}
sourceSets {
getByName("main") {
kotlin.directories += "src/main/kotlin"
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
flavorDimensions += "distributor"
productFlavors {
create("michas") {
dimension = "distributor"
buildConfigField("boolean", "FLAVOR_FDROID", "false")
}
create("fdroid") {
dimension = "distributor"
buildConfigField("boolean", "FLAVOR_FDROID", "true")
}
}
buildTypes {
getByName("debug") {
isMinifyEnabled = false
isShrinkResources = false
}
getByName("release") {
isMinifyEnabled = true
isShrinkResources = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard.pro"
)
}
}
}
dependencies {
implementation(libs.kotlin.stdlib)
implementation(libs.core.ktx)
implementation(libs.fragment.ktx)
implementation(libs.viewpager2)
implementation(libs.vectordrawable)
implementation(libs.okhttp)
implementation(libs.rxjava)
implementation(libs.rxandroid)
implementation(libs.jackson.core)
implementation(libs.picasso)
implementation(libs.freedroidwarn)
}
-27
View File
@@ -1,27 +0,0 @@
#!/bin/bash
set -e
cd "`dirname "$0"`"
dimensions=(mdpi:1 hdpi:1.5 xhdpi:2 xxhdpi:3 xxxhdpi:4)
res='../src/main/res'
cp 'launcher.svg' 'launcher-foreground.svg'
inkscape --select circle --verb EditDelete --verb=FileSave --verb=FileQuit \
'launcher-foreground.svg'
for dimension in ${dimensions[@]}; do
resource="${dimension%:*}"
scale="${dimension#*:}"
mkdir -p "$res/mipmap-$resource" "$res/drawable-$resource"
size="`bc <<< "48 * $scale"`"
inkscape 'launcher.svg' -a 15:15:93:93 -w "$size" -h "$size" \
-e "$res/mipmap-$resource/ic_launcher.png"
optipng "$res/mipmap-$resource/ic_launcher.png"
size="`bc <<< "108 * $scale"`"
inkscape 'launcher-foreground.svg' -w "$size" -h "$size" \
-e "$res/drawable-$resource/ic_launcher_foreground.png"
optipng "$res/drawable-$resource/ic_launcher_foreground.png"
done
rm 'launcher-foreground.svg'
-87
View File
@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" style="enable-background:new" id="svg3" version="1.1" viewBox="0 0 108 108"
height="108" width="108" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://purl.org/dc/elements/1.1/">
<metadata id="metadata55">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>-</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs id="defs17">
<clipPath id="paper-clip" clipPathUnits="userSpaceOnUse">
<path id="paper-clip-path" d="m 67.759585,28.469613 -18.355472,18.146485 -21.453125,-4.732422 9.087891,24.064453 25.894536,12.974609 12.37695,-23.86914 -1.93359,-0.66211 z" />
</clipPath>
<filter id="paper-inner-shadow">
<feFlood id="feFlood6" result="flood" flood-color="rgb(0,0,0)" flood-opacity="0.2" />
<feComposite id="feComposite8" result="composite1" operator="in" in2="SourceGraphic" in="flood" />
<feGaussianBlur id="feGaussianBlur10" result="blur" stdDeviation="2" in="composite1" />
<feOffset id="feOffset12" result="offset" dy="0" dx="0" />
<feComposite id="feComposite14" result="composite2" operator="over" in2="offset" in="SourceGraphic" />
</filter>
<filter id="paper-edge-1" style="color-interpolation-filters:sRGB">
<feFlood id="feFlood958" result="flood" flood-color="rgb(0,0,0)" flood-opacity="0.2" />
<feComposite id="feComposite960" result="composite1" operator="out" in2="SourceGraphic"
in="flood" />
<feGaussianBlur id="feGaussianBlur962" result="blur" stdDeviation="0" in="composite1" />
<feOffset id="feOffset964" result="offset" dy="0.2" dx="0.2" />
<feComposite id="feComposite966" result="composite2" operator="atop" in2="SourceGraphic"
in="offset" />
</filter>
<filter id="paper-edge-2" style="color-interpolation-filters:sRGB">
<feFlood id="feFlood1388" result="flood" flood-color="rgb(255,255,255)" flood-opacity="0.2" />
<feComposite id="feComposite1390" result="composite1" operator="out" in2="SourceGraphic"
in="flood" />
<feGaussianBlur id="feGaussianBlur1392" result="blur" stdDeviation="0" in="composite1" />
<feOffset id="feOffset1394" result="offset" dy="-0.1" dx="0.3" />
<feComposite id="feComposite1396" result="composite2" operator="atop" in2="SourceGraphic"
in="offset" />
</filter>
<filter id="paper-shadow" style="color-interpolation-filters:sRGB">
<feFlood id="feFlood1506" result="flood" flood-color="rgb(0,0,0)" flood-opacity="0.4" />
<feComposite id="feComposite1508" result="composite1" operator="in" in2="SourceGraphic"
in="flood" />
<feGaussianBlur id="feGaussianBlur1510" result="blur" stdDeviation="2" in="composite1" />
<feOffset id="feOffset1512" result="offset" dy="0" dx="0" />
<feComposite id="feComposite1514" result="composite2" operator="over" in2="offset" in="SourceGraphic" />
</filter>
<filter id="circle-shadow" style="color-interpolation-filters:sRGB">
<feFlood id="feFlood1626" result="flood" flood-color="rgb(255,255,255)" flood-opacity="0.2" />
<feComposite id="feComposite1628" result="composite1" operator="out" in2="SourceGraphic"
in="flood" />
<feGaussianBlur id="feGaussianBlur1630" result="blur" stdDeviation="0" in="composite1" />
<feOffset id="feOffset1632" result="offset" dy="0.5" dx="0" />
<feComposite id="feComposite1634" result="fbSourceGraphic" operator="atop" in2="SourceGraphic"
in="offset" />
<feFlood in="fbSourceGraphic" result="flood" flood-color="rgb(0,0,0)" flood-opacity="0.2"
id="feFlood1640" />
<feComposite result="composite1" operator="out" in="flood" id="feComposite1642" in2="fbSourceGraphic" />
<feGaussianBlur result="blur" stdDeviation="0" in="composite1" id="feGaussianBlur1644" />
<feOffset result="offset" dy="-0.5" dx="0" id="feOffset1646" />
<feComposite result="fbSourceGraphic" operator="atop" in="offset" id="feComposite1648"
in2="fbSourceGraphic" />
<feFlood in="fbSourceGraphic" result="flood" flood-color="rgb(0,0,0)" flood-opacity="0.2"
id="feFlood1664" />
<feComposite result="composite1" operator="in" in="flood" id="feComposite1666" in2="fbSourceGraphic" />
<feGaussianBlur result="blur" stdDeviation="1" in="composite1" id="feGaussianBlur1668" />
<feOffset result="offset" dy="1" dx="0" id="feOffset1670" />
<feComposite result="composite2" operator="over" in="fbSourceGraphic" id="feComposite1672"
in2="offset" />
</filter>
</defs>
<circle r="36" cy="54" cx="54" id="circle" style="fill:#262c38;filter:url(#circle-shadow)" />
<g style="filter:url(#paper-shadow)" id="paper-group">
<path d="m 67.75836,28.470764 -23.382292,23.115602 -0.0887,1.254642 29.189963,2.017946 z"
style="fill:#1976d2" id="paper-4" />
<path style="fill:#47a2fc;filter:url(#paper-inner-shadow)" d="m 27.949219,41.884766 9.08789,24.064453 25.894532,12.974609 12.376953,-23.86914 -22.298828,-7.638672 v -0.002 z"
clip-path="url(#paper-clip)" id="paper-3" />
<path d="m 53.009473,47.414648 -15.970174,18.53113 25.894116,12.97696 z" style="fill:#1976d2;filter:url(#paper-edge-1)"
id="paper-2" />
<path style="fill:#47a2fc;filter:url(#paper-edge-2)" d="m 53.009766,47.414016 9.923828,31.503906 12.375,-23.865234 z"
id="paper-1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.0 KiB

+29
View File
@@ -0,0 +1,29 @@
[versions]
core-ktx = "1.18.0"
fragment-ktx = "1.8.9"
freedroidwarn = "V1.10"
gradle = "9.1.0"
jackson-core = "2.21.2"
kotlin = "2.3.20"
okhttp = "5.3.2"
picasso = "2.71828"
rxandroid = "3.0.2"
rxjava = "3.1.12"
vectordrawable = "1.2.0"
viewpager2 = "1.1.0"
[libraries]
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" }
fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragment-ktx" }
freedroidwarn = { group = "com.github.woheller69", name = "FreeDroidWarn", version.ref = "freedroidwarn" }
jackson-core = { group = "com.fasterxml.jackson.core", name = "jackson-core", version.ref = "jackson-core" }
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
picasso = { group = "com.squareup.picasso", name = "picasso", version.ref = "picasso" }
rxandroid = { group = "io.reactivex.rxjava3", name = "rxandroid", version.ref = "rxandroid" }
rxjava = { group = "io.reactivex.rxjava3", name = "rxjava", version.ref = "rxjava" }
vectordrawable = { group = "androidx.vectordrawable", name = "vectordrawable", version.ref = "vectordrawable" }
viewpager2 = { group = "androidx.viewpager2", name = "viewpager2", version.ref = "viewpager2" }
[plugins]
android-application = { id = "com.android.application", version.ref = "gradle" }
Binary file not shown.
+5 -1
View File
@@ -1,5 +1,9 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
networkTimeout=10000
retries=0
retryBackOffMs=500
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+193 -117
View File
@@ -1,78 +1,128 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m"'
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -81,92 +131,118 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+48 -50
View File
@@ -1,84 +1,82 @@
@if "%DEBUG%" == "" @echo off
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Set local scope for the variables, and ensure extensions are enabled
setlocal EnableExtensions
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m"
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
"%COMSPEC%" /c exit 1
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
"%COMSPEC%" /c exit 1
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
@rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
:exitWithErrorLevel
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
"%COMSPEC%" /c exit %ERRORLEVEL%
-3
View File
@@ -1,3 +0,0 @@
* Allow to sort by date added and last update
* Display more compatibility information for packages
* Drop AppCompat and reduce APK file size
-3
View File
@@ -1,3 +0,0 @@
* Persist sorting order across application restarts
* Display Open Collective donation links
* Rework text strings
-4
View File
@@ -1,4 +0,0 @@
* Full text search
* Search results ranking
* Allow to view packages per repository
* Automatic day/night theme for Android 10
+6
View File
@@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
]
}
-5
View File
@@ -1,5 +0,0 @@
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
}
rootProject.name = "michas-droid"
include ':'
+24
View File
@@ -0,0 +1,24 @@
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
@Suppress("UnstableApiUsage")
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}
rootProject.name = "michas-droid"
include(":")
@@ -16,10 +16,12 @@ object Preferences {
private val subject = PublishSubject.create<Key<*>>()
private val keys = sequenceOf(Key.AutoSync, Key.IncompatibleVersions, Key.ProxyHost, Key.ProxyPort, Key.ProxyType,
Key.SortOrder, Key.Theme, Key.UpdateNotify, Key.UpdateUnstable).map { Pair(it.name, it) }.toMap()
private val keys = sequenceOf(
Key.AutoSync, Key.IncompatibleVersions, Key.ProxyHost, Key.ProxyPort, Key.ProxyType,
Key.SortOrder, Key.Theme, Key.UpdateNotify, Key.UpdateUnstable
).associateBy { it.name }
private val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, keyString ->
private val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, keyString ->
keys[keyString]?.let(subject::onNext)
}
@@ -89,6 +89,12 @@ data class Repository(
"Michachatz official repository. Everything in this repository is always built from the source code.",
21, true, "3546DCBDD900F280EE2161CC163C1156BE2C2F3EB810415115039E0C7D3242C0", ""
),
if (isFdroid) null else defaultRepository(
"https://repo.dgplayser.duckdns.org/fdroid/archive",
"Michachatz F-Droid Repo",
"Michachatz official repository. Everything in this repository is always built from the source code.",
21, true, "3546DCBDD900F280EE2161CC163C1156BE2C2F3EB810415115039E0C7D3242C0 ", ""
),
defaultRepository(
"https://f-droid.org/repo",
"F-Droid",
@@ -39,7 +39,7 @@ open class DrawableWrapper(val drawable: Drawable): Drawable() {
}
override fun getAlpha(): Int {
return DrawableCompat.getAlpha(drawable)
return drawable.alpha
}
override fun setAlpha(alpha: Int) {
@@ -74,5 +74,6 @@ open class DrawableWrapper(val drawable: Drawable): Drawable() {
DrawableCompat.setHotspotBounds(drawable, left, top, right, bottom)
}
@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
override fun getOpacity(): Int = drawable.opacity
}
@@ -260,6 +260,6 @@ class IndexHandler(private val repositoryId: Long, private val callback: Callbac
override fun characters(ch: CharArray, start: Int, length: Int) {
super.characters(ch, start, length)
contentBuilder.append(ch, start, length)
contentBuilder.appendRange(ch, start, start + length)
}
}
@@ -35,6 +35,7 @@ import android.widget.ProgressBar
import android.widget.Switch
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.ContextCompat.getString
import androidx.core.graphics.ColorUtils
import androidx.core.text.HtmlCompat
import androidx.core.text.util.LinkifyCompat
@@ -362,10 +363,10 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
}
}
@SuppressLint("ClickableViewAccessibility")
private open class OverlappingViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
init {
// Block touch events if touched above negative margin
@SuppressLint("ClickableViewAccessibility")
itemView.setOnTouchListener { v, event ->
val top = (v.layoutParams as ViewGroup.MarginLayoutParams).topMargin
event.action == MotionEvent.ACTION_DOWN && top < 0 && event.y < -top
@@ -384,8 +385,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
init {
val margin = measurement.invalidate(itemView.resources) {
@SuppressLint("SetTextI18n")
text.text = "measure"
text.text = itemView.context.getString(R.string.measure)
link.visibility = View.GONE
measurement.measure(itemView)
((itemView.measuredHeight - icon.measuredHeight) / 2f).roundToInt()
@@ -407,8 +407,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
init {
val margin = measurement.invalidate(itemView.resources) {
@SuppressLint("SetTextI18n")
text.text = "measure"
text.text = itemView.context.getString(R.string.measure)
measurement.measure(itemView)
((itemView.measuredHeight - icon.measuredHeight) / 2f).roundToInt()
}
@@ -148,8 +148,8 @@ class ProductFragment(): ScreenFragment(), ProductAdapter.Callbacks {
.flatMapSingle { products -> RxUtils
.querySingle { signal -> Database.RepositoryAdapter.getAll(signal) }
.map { result ->
result.asSequence().map { Pair(it.id, it) }.toMap()
.let { map -> products.mapNotNull { product -> map[product.repositoryId]?.let { Pair(product, it) } } } } }
result.associateBy { it.id }
.let { map -> products.mapNotNull { product -> map[product.repositoryId]?.let { Pair(product, it) } } } } }
.flatMapSingle { products -> RxUtils
.querySingle { signal -> Nullable(Database.InstalledAdapter.get(packageName, signal)) }
.map { result -> Pair(products, result) } }
@@ -396,9 +396,9 @@ class ProductFragment(): ScreenFragment(), ProductAdapter.Callbacks {
override fun onScreenshotClick(screenshot: Product.Screenshot) {
val pair = products.asSequence()
.map { it -> Pair(it.second, it.first.screenshots.find { it === screenshot }?.identifier) }
.filter { it.second != null }.firstOrNull()
if (pair != null) {
.map { it -> Pair(it.second, it.first.screenshots.find { it === screenshot }?.identifier) }
.firstOrNull { it.second != null }
if (pair != null) {
val (repository, identifier) = pair
if (identifier != null) {
ScreenshotsFragment(packageName, repository.id, identifier).show(childFragmentManager)
@@ -420,8 +420,9 @@ class ProductFragment(): ScreenFragment(), ProductAdapter.Callbacks {
MessageDialog(MessageDialog.Message.ReleaseSignatureMismatch).show(childFragmentManager)
}
else -> {
val productRepository = products.asSequence().filter { it -> it.first.releases.any { it === release } }.firstOrNull()
if (productRepository != null) {
val productRepository =
products.firstOrNull { it -> it.first.releases.any { it === release } }
if (productRepository != null) {
downloadConnection.binder?.enqueue(packageName, productRepository.first.name,
productRepository.second, release)
}
@@ -196,6 +196,12 @@ class ProductsAdapter(private val onClick: (ProductItem) -> Unit):
}
}
override fun areContentsTheSame(oldCursor: Cursor, newCursor: Cursor): Boolean {
val oldItem = Database.ProductAdapter.transformItem(oldCursor)
val newItem = Database.ProductAdapter.transformItem(newCursor)
return oldItem == newItem
}
@SuppressLint("NotifyDataSetChanged")
override fun onCursorChanged(oldCursor: Cursor?, newCursor: Cursor?) {
val oldSize = oldCursor?.count ?: 0
@@ -14,6 +14,7 @@ import androidx.core.os.BundleCompat
import androidx.core.view.WindowCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.michatec.store.BuildConfig
import com.michatec.store.R
import com.michatec.store.content.Cache
import com.michatec.store.content.Preferences
@@ -23,6 +24,7 @@ import com.michatec.store.utility.Utils
import com.michatec.store.utility.extension.android.*
import com.michatec.store.utility.extension.resources.*
import com.michatec.store.utility.extension.text.*
import org.woheller69.freeDroidWarn.FreeDroidWarn
abstract class ScreenActivity: FragmentActivity() {
companion object {
@@ -74,6 +76,8 @@ abstract class ScreenActivity: FragmentActivity() {
setTheme(Preferences[Preferences.Key.Theme].getResId(resources.configuration))
super.onCreate(savedInstanceState)
FreeDroidWarn.showWarningOnUpgrade(this, BuildConfig.VERSION_CODE)
WindowCompat.setDecorFitsSystemWindows(window, false)
addContentView(FrameLayout(this).apply { id = R.id.main_content },
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
@@ -561,6 +561,7 @@ class TabsFragment: ScreenFragment() {
override fun setAlpha(alpha: Int) = Unit
override fun setColorFilter(colorFilter: ColorFilter?) = Unit
@Deprecated("Deprecated in Java")
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
}
@@ -19,11 +19,11 @@ class Connection<B: IBinder, S: ConnectionService<B>>(private val serviceClass:
}
}
@Suppress("UNCHECKED_CAST")
override fun onServiceConnected(componentName: ComponentName, binder: IBinder) {
@Suppress("UNCHECKED_CAST")
binder as B
this.binder = binder
onBind?.invoke(this, binder)
val b = binder as B
this.binder = b
onBind?.invoke(this, b)
}
override fun onServiceDisconnected(componentName: ComponentName) {
@@ -331,7 +331,7 @@ class SyncService: ConnectionService<SyncService.Binder>() {
currentTask = null
handleNextTask(false)
val blocked = updateNotificationBlockerFragment?.get()?.isAdded == true
if (!blocked && result != null && result.isNotEmpty()) {
if (!blocked && !result.isNullOrEmpty()) {
displayUpdatesNotification(result)
}
}
@@ -12,7 +12,7 @@ import okhttp3.Response
object RxUtils {
private class ManagedDisposable(private val cancel: () -> Unit): Disposable {
@Volatile var disposed = false
var disposed = false
override fun isDisposed(): Boolean = disposed
override fun dispose() {
@@ -1,7 +1,6 @@
package com.michatec.store.utility
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.Signature
import android.content.res.Configuration
@@ -67,23 +66,18 @@ object Utils {
}
}
@SuppressLint("SuspiciousIndentation")
fun configureLocale(context: Context): Context {
val supportedLanguages = BuildConfig.LANGUAGES.toSet()
val configuration = context.resources.configuration
val currentLocales = if (Android.sdk(24)) {
val localesList = configuration.locales
(0 until localesList.size()).map(localesList::get)
} else {
@Suppress("DEPRECATION")
listOf(configuration.locale)
}
val localesList = configuration.locales
val currentLocales = (0 until localesList.size()).map(localesList::get)
val compatibleLocales = currentLocales
.filter { it.language in supportedLanguages }
.let { it.ifEmpty { listOf(Locale.US) } }
Locale.setDefault(compatibleLocales.first())
val newConfiguration = Configuration(configuration)
newConfiguration.setLocales(LocaleList(*compatibleLocales.toTypedArray()))
val newConfiguration = Configuration(configuration).apply {
setLocales(LocaleList(*compatibleLocales.toTypedArray()))
}
return context.createConfigurationContext(newConfiguration)
}
@@ -33,9 +33,8 @@ abstract class CursorRecyclerAdapter<VT: Enum<VT>, VH: RecyclerView.ViewHolder>:
return
}
// Further reduced threshold to 100 for DiffUtil to avoid any noticeable frame drops on the main thread.
// JSON parsing and DB access during diffing are slow.
if (oldSize > 100 || newSize > 100) {
// Increased threshold for DiffUtil and optimized callback
if (oldSize > 500 || newSize > 500) {
notifyDataSetChanged()
return
}
@@ -60,7 +59,6 @@ abstract class CursorRecyclerAdapter<VT: Enum<VT>, VH: RecyclerView.ViewHolder>:
})
diffResult.dispatchUpdatesTo(this)
} catch (_: Exception) {
// Fallback in case of cursor issues during diffing
notifyDataSetChanged()
}
}
@@ -12,11 +12,4 @@ class FragmentLinearLayout: LinearLayout {
init {
fitsSystemWindows = true
}
@Suppress("unused")
var percentTranslationY: Float
get() = height.let { if (it > 0) translationY / it else 0f }
set(value) {
translationY = value * height
}
}
+164
View File
@@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="action_failed">Aktion fehlgeschlagen</string>
<string name="add_repository">Repository hinzufügen</string>
<string name="address">Adresse</string>
<string name="all_applications">Alle Anwendungen</string>
<string name="all_applications_up_to_date">Alle Anwendungen sind aktuell</string>
<string name="already_exists">Existiert bereits</string>
<string name="always">Immer</string>
<string name="anti_features">Anti-Funktionen</string>
<string name="application">Anwendung</string>
<string name="application_not_found">Anwendung nicht gefunden</string>
<string name="author_email">E-Mail des Autors</string>
<string name="author_website">Website des Autors</string>
<string name="available">Verfügbar</string>
<string name="bug_tracker">Fehlerverfolgung</string>
<string name="cancel">Abbrechen</string>
<string name="cant_edit_sync_DESC">Repository kann nicht bearbeitet werden, da es gerade synchronisiert wird.</string>
<string name="changelog">Änderungsprotokoll</string>
<string name="changes">Änderungen</string>
<string name="checking_repository">Repository wird überprüft</string>
<string name="compiled_for_debugging">Für Debugging kompiliert</string>
<string name="confirmation">Bestätigung</string>
<string name="connecting">Verbinden</string>
<string name="contains_non_free_media">Enthält nicht-freie Medien</string>
<string name="could_not_download_FORMAT">Konnte %s nicht herunterladen</string>
<string name="could_not_sync_FORMAT">Konnte %s nicht synchronisieren</string>
<string name="could_not_validate_FORMAT">Konnte %s nicht validieren</string>
<string name="dark">Dunkel</string>
<string name="date_added">Hinzugefügt am</string>
<string name="delete">Löschen</string>
<string name="delete_repository_DESC">Möchtest du das Repository wirklich löschen?</string>
<string name="description">Beschreibung</string>
<string name="details">Details</string>
<string name="donate">Spenden</string>
<string name="downloaded_FORMAT">Heruntergeladen: %s</string>
<string name="downloading">Wird heruntergeladen</string>
<string name="downloading_FORMAT">Lade %s herunter</string>
<string name="edit_repository">Repository bearbeiten</string>
<string name="file_format_error_DESC">Ungültiges Dateiformat.</string>
<string name="fingerprint">Fingerabdruck</string>
<string name="has_advertising">Enthält Werbung</string>
<string name="has_non_free_dependencies">Hat nicht-freie Abhängigkeiten</string>
<string name="has_security_vulnerabilities">Hat Sicherheitslücken</string>
<string name="http_error_DESC">Ungültige Serverantwort.</string>
<string name="http_proxy">HTTP-Proxy</string>
<string name="ignore_all_updates">Alle Updates ignorieren</string>
<string name="ignore_this_update">Dieses Update ignorieren</string>
<string name="incompatible_api_DESC_FORMAT">Dein %1$s (API-Version %2$d) wird nicht unterstützt. %3$s</string>
<string name="incompatible_api_max_DESC_FORMAT">Maximale API-Version ist %d.</string>
<string name="incompatible_api_min_DESC_FORMAT">Minimale API-Version ist %d.</string>
<string name="incompatible_features_DESC">Fehlende Funktionen.</string>
<string name="incompatible_older_DESC">Diese Version ist älter als die auf deinem Gerät installierte. Bitte deinstalliere diese zuerst.</string>
<string name="incompatible_platforms_DESC_FORMAT">Deine %1$s-Plattform wird nicht unterstützt. Unterstützte Plattformen: %2$s.</string>
<string name="incompatible_signature_DESC">Diese Version wurde mit einem anderen Zertifikat signiert als die auf deinem Gerät installierte. Bitte deinstalliere diese zuerst.</string>
<string name="incompatible_version">Inkompatible Version</string>
<string name="incompatible_versions">Inkompatible Versionen</string>
<string name="incompatible_versions_summary">Zeige Versionen, die nicht mit dem Gerät kompatibel sind</string>
<string name="incompatible_with_FORMAT">Nicht kompatibel mit %s</string>
<string name="install">Installieren</string>
<string name="installed">Installiert</string>
<string name="integrity_check_error_DESC">Integrität konnte nicht überprüft werden.</string>
<string name="invalid_address">Ungültige Adresse</string>
<string name="invalid_fingerprint_format">Ungültiges Fingerabdruckformat</string>
<string name="invalid_metadata_error_DESC">Ungültige Metadaten.</string>
<string name="invalid_permissions_error_DESC">Ungültige Berechtigungen.</string>
<string name="invalid_signature_error_DESC">Ungültige Signatur.</string>
<string name="invalid_username_format">Ungültiges Benutzername-Format</string>
<string name="last_update">Letztes Update</string>
<string name="launch">Starten</string>
<string name="license">Lizenz</string>
<string name="license_FORMAT">Lizenz %s</string>
<string name="light">Hell</string>
<string name="link_copied_to_clipboard">Link in die Zwischenablage kopiert</string>
<string name="links">Links</string>
<string name="merging_FORMAT">Füge %s zusammen</string>
<string name="name">Name</string>
<string name="network_error_DESC">Netzwerkfehler.</string>
<string name="never">Nie</string>
<string name="new_updates_available">Neue Updates verfügbar</string>
<plurals name="new_updates_DESC_FORMAT">
<item quantity="one">%d neues Update.</item>
<item quantity="other">%d neue Updates.</item>
</plurals>
<string name="no_applications_available">Keine Anwendungen verfügbar</string>
<string name="no_applications_installed">Keine Anwendungen installiert</string>
<string name="no_description_available_DESC">Keine Beschreibung verfügbar.</string>
<string name="no_matching_applications_found">Keine passenden Anwendungen gefunden</string>
<string name="no_proxy">Kein Proxy</string>
<string name="notify_about_updates">Über Updates benachrichtigen</string>
<string name="notify_about_updates_summary">Benachrichtigung anzeigen, wenn Updates verfügbar sind</string>
<string name="number_of_applications">Anzahl der Anwendungen</string>
<string name="ok">OK</string>
<string name="only_compatible_with_FORMAT">Nur kompatibel mit %s</string>
<string name="only_on_wifi">Nur über WLAN</string>
<string name="open_DESC_FORMAT">%s öffnen?</string>
<string name="other">Andere</string>
<string name="parsing_index_error_DESC">Indexdatei konnte nicht verarbeitet werden.</string>
<string name="password">Passwort</string>
<string name="password_missing">Passwort fehlt</string>
<string name="permissions">Berechtigungen</string>
<string name="plus_more_FORMAT">+%d mehr</string>
<string name="preferences">Einstellungen</string>
<string name="processing_FORMAT">Verarbeite %1$s</string>
<string name="project_website">Projekt-Website</string>
<string name="promotes_non_free_network_services">Fördert nicht-freie Netzwerkdienste</string>
<string name="promotes_non_free_software">Fördert nicht-freie Software</string>
<string name="provided_by_FORMAT">Bereitgestellt von %s</string>
<string name="proxy">Proxy</string>
<string name="proxy_host">Proxy-Host</string>
<string name="proxy_port">Proxy-Port</string>
<string name="proxy_type">Proxy-Typ</string>
<string name="repositories">Repositories</string>
<string name="repository">Repository</string>
<string name="repository_not_used_DESC">Dieses Repository wurde noch nicht verwendet. Du musst es aktivieren, um die Anwendungen zu sehen.</string>
<string name="repository_unsigned_DESC">Nicht signiert. Die Anwendungsliste konnte nicht verifiziert werden. Sei vorsichtig beim Herunterladen.</string>
<string name="requires_FORMAT">Benötigt %s</string>
<string name="save">Speichern</string>
<string name="saving_details">Speichere Details</string>
<string name="screenshots">Screenshots</string>
<string name="search">Suchen</string>
<string name="select_mirror">Mirror auswählen</string>
<string name="show_more">Mehr anzeigen</string>
<string name="show_older_versions">Ältere Versionen anzeigen</string>
<string name="signature_FORMAT">Signatur %s</string>
<string name="signed_using_unsafe_algorithm">Mit unsicherem Algorithmus signiert</string>
<string name="skip">Überspringen</string>
<string name="socks_proxy">SOCKS-Proxy</string>
<string name="sorting_order">Sortierreihenfolge</string>
<string name="source_code">Quellcode</string>
<string name="source_code_no_longer_available">Quellcode nicht mehr verfügbar</string>
<string name="suggested">Empfohlen</string>
<string name="sync_repositories">Repositories synchronisieren</string>
<string name="sync_repositories_automatically">Repositories automatisch synchronisieren</string>
<string name="syncing">Synchronisiere</string>
<string name="syncing_FORMAT">Synchronisiere %s</string>
<string name="system">System</string>
<string name="tap_to_install_DESC">Tippen zum Installieren.</string>
<string name="theme">Design</string>
<string name="tracks_or_reports_your_activity">Verfolgt oder meldet deine Aktivitäten</string>
<string name="uninstall">Deinstallieren</string>
<string name="unknown">Unbekannt</string>
<string name="unknown_error_DESC">Unbekannter Fehler.</string>
<string name="unknown_FORMAT">Unbekannt: %s</string>
<string name="unsigned">Nicht signiert</string>
<string name="unstable_updates">Instabile Updates</string>
<string name="unstable_updates_summary">Instabile Versionen vorschlagen</string>
<string name="unverified">Nicht verifiziert</string>
<string name="update">Aktualisieren</string>
<string name="updates">Updates</string>
<string name="upstream_source_code_is_not_free">Quellcode ist nicht frei verfügbar</string>
<string name="username">Benutzername</string>
<string name="username_missing">Benutzername fehlt</string>
<string name="validation_index_error_DESC">Index konnte nicht validiert werden.</string>
<string name="version_FORMAT">Version %s</string>
<string name="versions">Versionen</string>
<string name="waiting_to_start_download">Warte auf Start des Downloads</string>
<string name="website">Website</string>
<string name="address_redirect_FORMAT">Die Repository-Adresse wurde zu %s weitergeleitet. Möchtest du diese verwenden?</string>
<string name="credits">Credits an Michatec</string>
<string name="credits_to_fork">Dies ist ein Fork von github.com/kitsunyan/foxy-droid.</string>
</resources>
+1
View File
@@ -166,5 +166,6 @@
<string name="address_redirect_FORMAT">The repository address was redirected to %s. Do you want to use it instead?</string>
<string name="credits">Credits to Michatec</string>
<string name="credits_to_fork">This is a fork from github.com/kitsunyan/foxy-droid.</string>
<string name="measure" translatable="false">measure</string>
</resources>