7Z;6(@EK$q*Jgif00I6*^ZGV+XB5uw*1R-@23yTw&WKD{s1;HTL;dO)%5i#`dc6b7;5@^{KU%N|A-$zsYw4)7LA{3`Zp>1
z-?K9_IE&z)dayUM)wd8K^29m-l$lFhi$zj0l!u~4;VGR6Y!?MAfBC^?QD53hy6VdD
z@eUZIui}~L%#SmajaRq1J|#>
z4m=o$vZ*34=ZWK2!QMNEcp2Lbc5N1q!lEDq(bz0b;WI9;e>l=CG9^n#ro`w>_0F$Q
zfZ={2QyTkfByC&gy;x!r*NyXXbk=a%~~(#K?<
zTke0HuF5{Q+~?@!KDXR|g+43$+;ab`^flS%miup_0OUTm=nIc%d5nLP)i308PIjl_YMF6cpQ__6&$n6it8K-
z8PIjl_YMF6cpQ_!r)L8IivW`WdK8mBs6PXdjR2DYdK8nCs73=4j{uVadK8oNjwX|E
wpAeHLsTu^*Y>Trk?aBtSQ(D-o$(D8Px^?ZI-PUB?
z*1fv!{YdHme3Fc8%cR@*@zc5A_nq&2=R47Hp@$-JF4Fz*;SLw5}K^y>s-s;V!}b2i=5=M-
zComP?ju>8Fe@=H@rlwe1l`J*6BTTo`9b$zjQ@HxrAhp0D#u?M~TxGC_!?ccCHCjt|
zF*PgJf@kJB`|Ml}cmsyrAjO#Kjr^E5p29w+#>$C`Q|54BoDv$fQ9D?3n32P9LPMIzu?LjNqggOH=1@T{9bMn*u8(GI
z!;MLTtFPHal^S>VcJdiYqX0VU|Rn@A}C1xOlxCribxes0~+n2
z6qDaIA2$?e`opx3_KW!rAgbpzU)gFdjAKXh|5w``#F0R|c)Y)Du0_Ihhz^S?k^pk%
zP>9|pIDx)xHH^_~+aA=^$M!<8K~Hy(71nJGf6`HnjtS=4X4=Hk^O71oNia2V{HUCC
zoN3RSBS?mZCLw;l4W4a+D8qc)XJS`pUJ5X-f^1ytxwr`@si$lAE?{4G|o;
zO0l>`rr?;~c;{ZEFJ!!3=7=FdGJ?Q^xfNQh4A?i;IJ4}B+A?4olTK(fN++3CRBP97
ze~lG9h%oegkn)lpW-4F8o2`*WW0mZHwHez`ko@>U1_;EC_6ig|Drn@=DMV9YEUSCa
zIf$kHei3(u#zm9I!Jf(4t`Vm1lltJ&lVHy(eIXE8sy9sUpmz%I_gA#8x^Zv8%w?r2
z{GdkX1SkzRIr>prRK@rqn9j2wG|rUvf6PJbbin=yy-TAXrguvzN8jL$hUrIXzr^s5
zVM?H4;eM-QeRFr06@ifV(ocvk?_)~N@1c2ien56UjWXid6W%6ievIh)>dk|rIs##^kY67ib8Kw%#-oVFaXG7$ERyA9(NSJUvWiOA5H(!{uOpcW
zg&-?iqPhds%3%tFspHDqqr;A!e@B#iPQjHd=c>N1LoOEGRehVoPOdxJ>b6>yc#o#+
zl8s8!(|NMeqjsy@0x{8^j0d00SqRZjp{Kj)&4UHYGxG+z9b-)72I*&J70?+8e?p_@
z=>-(>l6z5vYlP~<2%DU02b!mA{7mS)NS_eLe=t)sm&+Pmk?asOEKlkPQ)EUvvfC=;4M&*|I!w}(@V_)eUKLA_t^%`o
z0PM9LV|UKTLnk|?M3u!|f2S0?UqZsEIH9*NJS-8lzu;A6-rr-ot=dg9SASoluZUkFH$7X;
zP=?kYX!K?JL-b~<#7wU;b;eS)O;@?h%sPPk{4xEBxb{!sm0AY|f9cNvx6>$3F!*0c
z75H=dy8JvTyO8}g1w{$9T$p~5en}AeSLoCF>_RT9YPMpChUjl310o*$QocjbH&
zbnwg#gssR#jDVN{uEi3n(PZ%PFZ|6J2
z5_rBf0-u>e4sFe0*Km49ATi7>Kn0f9!uc|rRMR1Dtt6m1LW8^>qFlo}h$@br=Rmpi
z;mI&>OF64Be{dVeHI8utrh)v^wsZ0jii%x8UgZ8TC%K~@I(4E};GFW&(;WVov}3%H
zH;IhRkfD^(vt^DjZz(MyHLZxv8}qzPc(%itBkBwf_fC~sDBgh<3XAv5cxxfF3<2U!
z03Xe&z`is!JDHbe;mNmfkH+_LFE*I2^mdL@7(@9DfAcP6O04V-ko;Rpgp<%Cj5r8Z
zd0`sXoIjV$j)--;jA6Zy^D5&5v$o^>e%>Q?9GLm{i~p^lAn!%ZtF$I~>39XVZxk0b
zROh^Bk9cE0AJBLozZIEmy7xG(yHWGztvfnr0(2ro1%>zsGMS^EMu+S$r=_;9
zWwZkgf7Q7`H9sLf2Go^Xy6&h~a&%s2_T@_Csf19MntF$aVFiFkvE3_hUg(B@&Xw@YJ
zpL$wNYf78=0c@!QU6_a$>CPiXT7QAGDM}7Z(0z#_ZA=fmLUj{2z7@Ypo71UDy8GHr
z-&TLKf6a5WCf@Adle3VglBt4>Z>;xF}}-S~B7<(%B;Y
z0QR55{z-buw>8ilNM3u6I+D$S%?)(p>=eBx-HpvZj{7c*_?K=d()*7q?93us}1dq%FAFYLsW8ZTQ_XZLh`P2*6(NgS}qGcfGXVWpwsp#Rs}IuKbk*`2}&)
zI^Vsk6S&Q4@oYS?dJ`NwMVBs6f57+RxdqVub#PvMu?$=^OJy5xEl0<5SLsSRy%%a0
zi}Y#1-F3m;Ieh#Y12UgW?-R)|eX>ZuF-2cc!1>~NS|XSF-6In>zBoZg+ml!6%fk7U
zw0LHcz8VQk(jOJ+Yu)|^|15ufl$KQd_1eUZZzj`aC%umU6F1&D5XVWce_wAe(qCSZ
zpX-QF4e{EmEVN9~6%bR5U*UT{eMHfcUo`jw*u?4r2s_$`}U{?NjvEm(u&<>B|%mq$Q3weshxk
z76<``8vh{+nX`@9CB6IE&z)I%IFjR^LH{s1p|eppv=x
za(g_jLU|xjWMAn-V7th$f({|LG8zzIE0g?cyW;%Dmtv%C+0@xVxPE^
zyZzi9P%JAD6ynwHptuzP`Kox7*9h7XSMonCalv;Md0i9Vb-c*!f0ubfk?&T&T}AHh
z4m8Bz{JllKcdNg?D^%a5MFQ;#1z|*}H^qHLzW)L}wp?2tY7RejtSh8<;Zw)QGJYUm
z|MbTxyj*McKlStlT9I5XlSWtQGN&-LTr2XyNU+`490rg?LYLMRnz-@oKqT1hpCGqP
zyRXt4=_Woj$%n5ee<3zhLF>5>`?m9a#xQH+Jk_+|RM8Vi;2*XbK-
zEL6sCpaGPzP>k8f4Kh|##_imt#zJMB;ir|JrMPGW`rityK1vHXMLy18%qmMQAm4WZ
zP)i30KR&5vs15)C+8dM66&$k~i|ZT;KR&5vs15)C+8dJ(sAmGPijyIz6_bsqKLSFH
zlOd=TljEpH0>h4zA*dCTK&emy#FCRCs1=i^sZ9bFmXjf<6_X39E(XY)00000#N437
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 68e8816d71c..2b189974c29 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
+distributionSha256Sum=5b9c5eb3f9fc2c94abaea57d90bd78747ca117ddbbf96c859d3741181a12bf2a
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
From c35b537a5225a3612232cd28cc908391827cf532 Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Thu, 15 Aug 2024 16:42:44 +0300
Subject: [PATCH 055/144] +39 links and 2 updates (#2260)
* +38 links
* Updates, renaming
* +1 link
* Minor fix
---
app/assets/appfilter.xml | 45 ++++++++++++++++++++++++++++++---
svgs/bill_payment_organizer.svg | 2 +-
svgs/databackup.svg | 2 +-
svgs/mi_video.svg | 2 +-
4 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index a50d84f2db4..6ba531a09bb 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -176,6 +176,7 @@
+
@@ -1020,6 +1021,7 @@
+
@@ -1149,6 +1151,7 @@
+
@@ -1325,6 +1328,8 @@
+
+
@@ -1926,6 +1931,7 @@
+
@@ -2246,7 +2252,6 @@
-
@@ -2440,6 +2445,7 @@
+
@@ -3090,6 +3096,7 @@
+
@@ -3692,6 +3699,7 @@
+
@@ -3768,6 +3776,7 @@
+
@@ -3914,6 +3923,8 @@
+
+
@@ -3959,6 +3970,9 @@
+
+
+
@@ -4060,6 +4074,8 @@
+
+
@@ -4068,6 +4084,7 @@
+
@@ -4133,6 +4150,7 @@
+
@@ -4308,6 +4326,7 @@
+
@@ -4398,6 +4417,7 @@
+
@@ -5658,8 +5678,6 @@
-
-
@@ -6229,6 +6247,7 @@
+
@@ -6353,6 +6372,7 @@
+
@@ -6377,6 +6397,7 @@
+
@@ -6502,6 +6523,7 @@
+
@@ -7072,6 +7094,7 @@
+
@@ -7754,6 +7777,7 @@
+
@@ -7870,6 +7894,7 @@
+
@@ -8403,6 +8428,7 @@
+
@@ -9436,6 +9462,7 @@
+
@@ -9559,6 +9586,7 @@
+
@@ -9572,6 +9600,7 @@
+
@@ -9701,8 +9730,10 @@
+
+
@@ -9776,6 +9807,7 @@
+
@@ -10049,6 +10081,7 @@
+
@@ -10170,6 +10203,7 @@
+
@@ -10790,6 +10824,7 @@
+
@@ -10817,6 +10852,7 @@
+
@@ -11184,6 +11220,7 @@
+
@@ -11989,6 +12026,7 @@
+
@@ -12117,6 +12155,7 @@
+
diff --git a/svgs/bill_payment_organizer.svg b/svgs/bill_payment_organizer.svg
index 91956fae8ce..593d919fb73 100644
--- a/svgs/bill_payment_organizer.svg
+++ b/svgs/bill_payment_organizer.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/databackup.svg b/svgs/databackup.svg
index 532a76cd4a9..f6a6fe1a193 100644
--- a/svgs/databackup.svg
+++ b/svgs/databackup.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/mi_video.svg b/svgs/mi_video.svg
index d0ba29e3ed5..28301a125e0 100644
--- a/svgs/mi_video.svg
+++ b/svgs/mi_video.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
From d5712a2f8930e3fce327e0a496980a6f83ecc865 Mon Sep 17 00:00:00 2001
From: Zongle Wang
Date: Fri, 16 Aug 2024 07:01:35 -0400
Subject: [PATCH 056/144] Fix edge-to-edge on three-button nav bar (#2261)
---
app/src/main/kotlin/app/lawnchair/lawnicons/MainActivity.kt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/MainActivity.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/MainActivity.kt
index 9b9b1829f96..e48505dff3d 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/MainActivity.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/MainActivity.kt
@@ -6,6 +6,7 @@ import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.util.Log
+import android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
@@ -32,6 +33,9 @@ class MainActivity : ComponentActivity() {
installSplashScreen()
super.onCreate(savedInstanceState)
enableEdgeToEdge()
+ // Fix for three-button nav not properly going edge-to-edge.
+ // TODO: https://issuetracker.google.com/issues/298296168
+ window.setFlags(FLAG_LAYOUT_NO_LIMITS, FLAG_LAYOUT_NO_LIMITS)
val isIconPicker = intent?.action == Constants.ICON_PICKER_INTENT_ACTION
From c7513c81d78130aec94190529057be5551bd86d2 Mon Sep 17 00:00:00 2001
From: Ishaan <81937191+5h3r10k@users.noreply.github.com>
Date: Fri, 16 Aug 2024 19:31:20 -0400
Subject: [PATCH 057/144] +2 icons and -1 typo (#2239)
* typo fix in "contributing.md"
* added Marcus logo and appfilter
* added NJ Transit logo and appfilter
* added ParkMobile logo and appfilter
* added Snackpass logo and appfilter
* added YI Home logo and appfilter
* updated icon sizes
i downloaded and tested the debug apk, the icon sizes were too small, fixed that
* adjusted stroke and sizes
* updated icons and sizes
redid marcus and nj_transit icon, modified snackpass, parkmobile, yi_home. Adjusted sizes of all
* removed nj transit for now, will rework and re-add at a later time
* updated sizes and strokes of icons
* fixed snackpass and yi home
fixed size of snackpass, fixed accidental fill on yi home
* removed icons to troubleshoot
---
CONTRIBUTING.md | 2 +-
app/assets/appfilter.xml | 2 ++
svgs/marcus.svg | 8 ++++++++
svgs/parkmobile.svg | 4 ++++
4 files changed, 15 insertions(+), 1 deletion(-)
create mode 100644 svgs/marcus.svg
create mode 100644 svgs/parkmobile.svg
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3b24acddbfe..52513979e45 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -125,7 +125,7 @@ Correct
## Adding an icon to Lawnicons
Here's how to add an icon to Lawnicons:
-### Prerequesties
+### Prerequisites
* Your icon in the SVG format, adhering to the [above guidelines](#contributing-icons). The filename must use snake case (e.g. `files_by_google.svg`).
* The package and activity name of the app.
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index 6ba531a09bb..f103bce295c 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -5449,6 +5449,7 @@
+
@@ -7182,6 +7183,7 @@
+
diff --git a/svgs/marcus.svg b/svgs/marcus.svg
new file mode 100644
index 00000000000..c821d9711a3
--- /dev/null
+++ b/svgs/marcus.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/svgs/parkmobile.svg b/svgs/parkmobile.svg
new file mode 100644
index 00000000000..2264a6eb30f
--- /dev/null
+++ b/svgs/parkmobile.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
From e61aead7297c38411bb598b5799e8c56eab2ccd7 Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Sat, 17 Aug 2024 12:56:26 +0300
Subject: [PATCH 058/144] Updating the self-review checklist (#2262)
* Updating the self-review checklist
* Minor fix
---
.github/icon_checklist.md | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/.github/icon_checklist.md b/.github/icon_checklist.md
index b4909874fd6..64b8cb378d3 100644
--- a/.github/icon_checklist.md
+++ b/.github/icon_checklist.md
@@ -6,21 +6,21 @@ While waiting for a review from our team, you can do a self-review to ensure tha
1. Canvas: `192×192px`.
2. Non-square icons: the long side of the icons should be `160px`.
3. Square icons: `154×154px`.
-
+- [ ] Done
### Color, stroke width and rounding
1. Color: black `#000`.
2. No fill. Base stroke width: `12px`. `14px`, `10px`, `8px` — depending on the shape of the icons. `6px` — for fine details.
3. Rounded ends and joins. 90° corners are rounded by `6-32px`.
-
+- [ ] Done
### Naming
1. Names should match the official app name and contain no additional text.
-2. If the first `3` characters of the app name contain letters not from the English alphabet, then add a localized (or transliterated) name via `~~`.
-Example: `京东 ~~ JD`.
+2. If the first `3` characters of the app name contain letters not from the English alphabet, then add a localized (or transliterated) name via `~~`. Example: `京东 ~~ JD`.
3. The names of the drawables should repeat the names of the apps if nothing prevents it.
-
+- [ ] Done
### Quality
1. Ensure that icons are easily recognizable.
2. Align icons to [the visual center](https://crazybitsstudios.com/another-way-of-aligning-elements-when-creating-icons) as much as possible within the guidelines. The visual center is where your icon looks and feels centered.
3. Avoid noticable black spots by reducing the stroke width or simplifying the icons.
4. Avoid close distances between strokes. The icons on the phone screen will be smaller, so the small distances between the strokes will stick together.
5. Avoid drastic changes in stroke widths. When the strokes next to each other differ in width by 4px or more, the icon will look sloppy.
+- [ ] Done
From c6771a8eff6f04ce4bf19d4d2f7b095ccf0c3496 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Sun, 18 Aug 2024 14:15:16 +0800
Subject: [PATCH 059/144] Fix crash when search results are 0
Fix #2258
---
.../lawnicons/ui/components/home/search/SearchContents.kt | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
index 369dff1632e..702e28652c0 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
@@ -173,7 +173,12 @@ private fun IconInfoListItem(iconInfo: ImmutableList) {
.padding(PaddingValues(16.dp)),
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
- val it = iconInfo[0]
+ val it = try {
+ iconInfo[0]
+ } catch (_: Exception) {
+ return@IconInfoListItem
+ }
+
val isIconInfoAppfilterShown = remember { mutableStateOf(false) }
ListItem(
From ab5b665a17c64992bb64b8bd7e148a1154cbb2ea Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Sun, 18 Aug 2024 14:25:57 +0800
Subject: [PATCH 060/144] Improve edge-to-edge handling
---
.../app/lawnchair/lawnicons/MainActivity.kt | 41 ++++---
.../app/lawnchair/lawnicons/ui/Lawnicons.kt | 101 ++++++++----------
.../ui/components/SetupEdgeToEdge.kt | 31 ++++++
3 files changed, 105 insertions(+), 68 deletions(-)
create mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/SetupEdgeToEdge.kt
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/MainActivity.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/MainActivity.kt
index e48505dff3d..a1b47407bd0 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/MainActivity.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/MainActivity.kt
@@ -6,14 +6,16 @@ import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.util.Log
-import android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
+import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
+import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.DrawableCompat
@@ -21,6 +23,8 @@ import androidx.core.graphics.drawable.toBitmap
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import app.lawnchair.lawnicons.model.IconInfo
import app.lawnchair.lawnicons.ui.Lawnicons
+import app.lawnchair.lawnicons.ui.components.SetupEdgeToEdge
+import app.lawnchair.lawnicons.ui.theme.LawniconsTheme
import app.lawnchair.lawnicons.ui.util.Constants
import dagger.hilt.android.AndroidEntryPoint
@@ -33,27 +37,37 @@ class MainActivity : ComponentActivity() {
installSplashScreen()
super.onCreate(savedInstanceState)
enableEdgeToEdge()
- // Fix for three-button nav not properly going edge-to-edge.
- // TODO: https://issuetracker.google.com/issues/298296168
- window.setFlags(FLAG_LAYOUT_NO_LIMITS, FLAG_LAYOUT_NO_LIMITS)
val isIconPicker = intent?.action == Constants.ICON_PICKER_INTENT_ACTION
setContent {
val context = LocalContext.current
val windowSizeClass = calculateWindowSizeClass(this)
- Lawnicons(
- windowSizeClass = windowSizeClass,
- onSendResult = { iconInfo ->
- setResult(context, iconInfo)
- finish()
- },
- isIconPicker = isIconPicker,
- )
+ LawniconsTheme {
+ val isExpandedScreen =
+ windowSizeClass.widthSizeClass == WindowWidthSizeClass.Expanded
+
+ val navBarColor = if (isExpandedScreen) {
+ MaterialTheme.colorScheme.background.copy(alpha = 0.95f)
+ } else {
+ MaterialTheme.colorScheme.surfaceContainer
+ }
+
+ SetupEdgeToEdge(navBarColor.toArgb())
+ Lawnicons(
+ isExpandedScreen = isExpandedScreen,
+ onSendResult = { iconInfo ->
+ setIntentResult(context, iconInfo)
+ finish()
+ },
+ isIconPicker = isIconPicker,
+ )
+ }
}
}
- private fun setResult(
+ @Suppress("DEPRECATION")
+ private fun setIntentResult(
context: Context,
iconInfo: IconInfo,
) {
@@ -89,7 +103,6 @@ class MainActivity : ComponentActivity() {
}
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconInfo.id)
setResult(RESULT_OK, intent)
- finish()
} else {
setResult(RESULT_CANCELED, intent)
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt
index 052f6000522..5fa7cc626f1 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt
@@ -4,8 +4,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
-import androidx.compose.material3.windowsizeclass.WindowSizeClass
-import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
@@ -20,7 +18,6 @@ import app.lawnchair.lawnicons.ui.destination.Acknowledgement
import app.lawnchair.lawnicons.ui.destination.Acknowledgements
import app.lawnchair.lawnicons.ui.destination.Contributors
import app.lawnchair.lawnicons.ui.destination.Home
-import app.lawnchair.lawnicons.ui.theme.LawniconsTheme
import app.lawnchair.lawnicons.ui.util.About
import app.lawnchair.lawnicons.ui.util.Acknowledgement
import app.lawnchair.lawnicons.ui.util.Acknowledgements
@@ -33,7 +30,7 @@ import soup.compose.material.motion.animation.rememberSlideDistance
@Composable
@ExperimentalFoundationApi
fun Lawnicons(
- windowSizeClass: WindowSizeClass,
+ isExpandedScreen: Boolean,
onSendResult: (IconInfo) -> Unit,
modifier: Modifier = Modifier,
isIconPicker: Boolean = false,
@@ -41,57 +38,53 @@ fun Lawnicons(
val navController = rememberNavController()
val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
val slideDistance = rememberSlideDistance()
- val isExpandedScreen = windowSizeClass.widthSizeClass == WindowWidthSizeClass.Expanded
-
- LawniconsTheme {
- Surface(
- modifier = modifier.fillMaxSize(),
- color = MaterialTheme.colorScheme.background,
+ Surface(
+ modifier = modifier.fillMaxSize(),
+ color = MaterialTheme.colorScheme.background,
+ ) {
+ NavHost(
+ navController = navController,
+ startDestination = Home,
+ enterTransition = { materialSharedAxisXIn(!isRtl, slideDistance) },
+ exitTransition = { materialSharedAxisXOut(!isRtl, slideDistance) },
+ popEnterTransition = { materialSharedAxisXIn(isRtl, slideDistance) },
+ popExitTransition = { materialSharedAxisXOut(isRtl, slideDistance) },
) {
- NavHost(
- navController = navController,
- startDestination = Home,
- enterTransition = { materialSharedAxisXIn(!isRtl, slideDistance) },
- exitTransition = { materialSharedAxisXOut(!isRtl, slideDistance) },
- popEnterTransition = { materialSharedAxisXIn(isRtl, slideDistance) },
- popExitTransition = { materialSharedAxisXOut(isRtl, slideDistance) },
- ) {
- composable {
- Home(
- onNavigate = { navController.navigate(About) },
- isExpandedScreen = isExpandedScreen,
- isIconPicker = isIconPicker,
- onSendResult = onSendResult,
- )
- }
- composable {
- Acknowledgements(
- onBack = navController::popBackStack,
- onNavigate = {
- navController.navigate(Acknowledgement(it))
- },
- isExpandedScreen = isExpandedScreen,
- )
- }
- composable { backStackEntry ->
- val acknowledgement: Acknowledgement = backStackEntry.toRoute()
- Acknowledgement(
- name = acknowledgement.id,
- onBack = navController::popBackStack,
- isExpandedScreen = isExpandedScreen,
- )
- }
- composable {
- About(
- onBack = navController::popBackStack,
- onNavigateToContributors = { navController.navigate(Contributors) },
- onNavigateToAcknowledgements = { navController.navigate(Acknowledgements) },
- isExpandedScreen = isExpandedScreen,
- )
- }
- composable {
- Contributors(onBack = navController::popBackStack, isExpandedScreen = isExpandedScreen)
- }
+ composable {
+ Home(
+ onNavigate = { navController.navigate(About) },
+ isExpandedScreen = isExpandedScreen,
+ isIconPicker = isIconPicker,
+ onSendResult = onSendResult,
+ )
+ }
+ composable {
+ Acknowledgements(
+ onBack = navController::popBackStack,
+ onNavigate = {
+ navController.navigate(Acknowledgement(it))
+ },
+ isExpandedScreen = isExpandedScreen,
+ )
+ }
+ composable { backStackEntry ->
+ val acknowledgement: Acknowledgement = backStackEntry.toRoute()
+ Acknowledgement(
+ name = acknowledgement.id,
+ onBack = navController::popBackStack,
+ isExpandedScreen = isExpandedScreen,
+ )
+ }
+ composable {
+ About(
+ onBack = navController::popBackStack,
+ onNavigateToContributors = { navController.navigate(Contributors) },
+ onNavigateToAcknowledgements = { navController.navigate(Acknowledgements) },
+ isExpandedScreen = isExpandedScreen,
+ )
+ }
+ composable {
+ Contributors(onBack = navController::popBackStack, isExpandedScreen = isExpandedScreen)
}
}
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/SetupEdgeToEdge.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/SetupEdgeToEdge.kt
new file mode 100644
index 00000000000..f4a7b79854d
--- /dev/null
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/SetupEdgeToEdge.kt
@@ -0,0 +1,31 @@
+package app.lawnchair.lawnicons.ui.components
+
+import androidx.activity.ComponentActivity
+import androidx.activity.SystemBarStyle
+import androidx.activity.enableEdgeToEdge
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.ui.graphics.luminance
+import androidx.compose.ui.graphics.toArgb
+
+@Composable
+fun ComponentActivity.SetupEdgeToEdge(
+ scrimColor: Int,
+) {
+ val contentColor = MaterialTheme.colorScheme.onBackground.toArgb()
+ val isDarkTheme = MaterialTheme.colorScheme.surface.luminance() < 0.5f
+
+ LaunchedEffect(Unit) {
+ enableEdgeToEdge(
+ navigationBarStyle = if (isDarkTheme) {
+ SystemBarStyle.dark(scrimColor)
+ } else {
+ SystemBarStyle.light(
+ scrimColor,
+ contentColor,
+ )
+ },
+ )
+ }
+}
From 83ec23e9c2fce73a582e05f35173d658fac1c186 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Sun, 18 Aug 2024 14:26:26 +0800
Subject: [PATCH 061/144] Fix crash when search is expanded and app is in
background
---
.../app/lawnchair/lawnicons/repository/IconRepository.kt | 2 +-
.../kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt | 4 ----
.../app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt | 2 ++
3 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt
index dee296b010b..1c18cdda2e8 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt
@@ -95,7 +95,7 @@ class IconRepositoryImpl @Inject constructor(application: Application) : IconRep
}.toPersistentList()
_searchedIconInfoModel.value = IconInfoModel(
- iconCount = _iconInfoModel.value.iconCount,
+ iconCount = _searchedIconInfoModel.value.iconCount,
iconInfo = filteredIcons,
)
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
index 111e8127e87..3e98e37a917 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
@@ -49,10 +49,6 @@ fun Home(
val iconInfoModel by iconInfoModel.collectAsStateWithLifecycle()
val searchedIconInfoModel by searchedIconInfoModel.collectAsStateWithLifecycle()
val iconRequestModel by iconRequestModel.collectAsStateWithLifecycle()
- val searchMode = searchMode
- val searchTerm = searchTerm
-
- var expandSearch by remember { mutableStateOf(false) }
val context = LocalContext.current
val lazyGridState = rememberLazyGridState()
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt
index 153d44305d4..69fbd2e5f57 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt
@@ -30,6 +30,8 @@ class LawniconsViewModel @Inject constructor(
@JvmField
val isIconRequestButtonClicked = userTipsRepository.hasClickedIconRequestButton()
+ var expandSearch by mutableStateOf(false)
+
private var _searchMode by mutableStateOf(SearchMode.LABEL)
private var _searchTerm by mutableStateOf("")
From 2a2fbf337617a4b78defdc194083430be991575a Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Mon, 19 Aug 2024 16:03:54 +0300
Subject: [PATCH 062/144] +17 links and 5 updates (#2269)
* 2 updates
* Spotify update
* +17 links
---
app/assets/appfilter.xml | 17 +++++++++++++++++
svgs/github.svg | 2 +-
svgs/spotiflyer.svg | 2 +-
svgs/spotify.svg | 2 +-
svgs/spotify_artists.svg | 2 +-
svgs/spotify_podcasters.svg | 2 +-
6 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index f103bce295c..8be042b3d7f 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -1114,6 +1114,7 @@
+
@@ -2120,6 +2121,7 @@
+
@@ -3691,6 +3693,7 @@
+
@@ -4434,6 +4437,7 @@
+
@@ -4726,6 +4730,7 @@
+
@@ -5368,6 +5373,7 @@
+
@@ -5995,6 +6001,7 @@
+
@@ -6398,6 +6405,7 @@
+
@@ -7596,6 +7604,7 @@
+
@@ -9464,6 +9473,8 @@
+
+
@@ -9563,6 +9574,7 @@
+
@@ -9966,6 +9978,7 @@
+
@@ -10808,6 +10821,7 @@
+
@@ -11740,6 +11754,7 @@
+
@@ -11931,6 +11946,7 @@
+
@@ -12282,6 +12298,7 @@
+
diff --git a/svgs/github.svg b/svgs/github.svg
index 4e7b4223282..6cbd5ff925a 100644
--- a/svgs/github.svg
+++ b/svgs/github.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/spotiflyer.svg b/svgs/spotiflyer.svg
index d1d5867cc61..da9569a7223 100644
--- a/svgs/spotiflyer.svg
+++ b/svgs/spotiflyer.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/spotify.svg b/svgs/spotify.svg
index c7181f838fc..28c5a6c41e5 100644
--- a/svgs/spotify.svg
+++ b/svgs/spotify.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/spotify_artists.svg b/svgs/spotify_artists.svg
index 1af294315e9..6b6f4650261 100644
--- a/svgs/spotify_artists.svg
+++ b/svgs/spotify_artists.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/spotify_podcasters.svg b/svgs/spotify_podcasters.svg
index 82566e29d12..4f99f8a5ee3 100644
--- a/svgs/spotify_podcasters.svg
+++ b/svgs/spotify_podcasters.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
From 126f09ef6695c8b67ea50b6a5343f1334bf5d709 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 22 Aug 2024 08:07:01 +0800
Subject: [PATCH 063/144] Update dependency androidx.compose:compose-bom to
v2024.08.00 (#2272)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
app/build.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index cf40ff1629a..848bf47d053 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -135,7 +135,7 @@ dependencies {
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.activity:activity-compose:1.9.1")
- implementation(platform("androidx.compose:compose-bom:2024.06.00"))
+ implementation(platform("androidx.compose:compose-bom:2024.08.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.ui:ui-util")
From 6e6c39534e6ec1f29362df4b1879e64b76315419 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 22 Aug 2024 08:07:09 +0800
Subject: [PATCH 064/144] Update dependency
androidx.navigation:navigation-compose to v2.8.0-rc01 (#2271)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
app/build.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 848bf47d053..5eac5f76308 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -144,7 +144,7 @@ dependencies {
implementation("androidx.compose.material:material-icons-core-android:1.6.8")
implementation("androidx.compose.material3:material3:1.3.0-beta05")
implementation("androidx.compose.material3:material3-window-size-class")
- implementation("androidx.navigation:navigation-compose:2.8.0-beta07")
+ implementation("androidx.navigation:navigation-compose:2.8.0-rc01")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1")
From c86521a65831bbd0f15f4b329bae77822685db2f Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 22 Aug 2024 08:07:17 +0800
Subject: [PATCH 065/144] Update dependency
androidx.compose.material3:material3 to v1.3.0-rc01 (#2270)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
app/build.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 5eac5f76308..cf9f33d9ef0 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -142,7 +142,7 @@ dependencies {
debugImplementation("androidx.compose.ui:ui-tooling")
implementation("androidx.compose.animation:animation")
implementation("androidx.compose.material:material-icons-core-android:1.6.8")
- implementation("androidx.compose.material3:material3:1.3.0-beta05")
+ implementation("androidx.compose.material3:material3:1.3.0-rc01")
implementation("androidx.compose.material3:material3-window-size-class")
implementation("androidx.navigation:navigation-compose:2.8.0-rc01")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4")
From 43d2105a97b860917122930eb3eb3608a4443382 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 22 Aug 2024 08:07:25 +0800
Subject: [PATCH 066/144] Update plugin com.gradle.develocity to v3.18 (#2268)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
settings.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/settings.gradle.kts b/settings.gradle.kts
index f0ac4ed0e4a..8ac7d615286 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -13,7 +13,7 @@ pluginManagement {
// https://docs.gradle.com/enterprise/gradle-plugin/
plugins {
- id("com.gradle.develocity") version "3.17.6"
+ id("com.gradle.develocity") version "3.18"
}
develocity {
From f4bf48e57771302e76b7dda91760c7618b520fb6 Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Thu, 22 Aug 2024 08:56:15 +0300
Subject: [PATCH 067/144] +6 links (#2274)
---
app/assets/appfilter.xml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index 8be042b3d7f..1675e806208 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -796,6 +796,7 @@
+
@@ -1754,6 +1755,7 @@
+
@@ -2084,6 +2086,7 @@
+
@@ -2162,7 +2165,7 @@
-
+
@@ -5143,6 +5146,7 @@
+
@@ -7214,6 +7218,7 @@
+
@@ -11969,6 +11974,7 @@
+
From 3d38b0ac0736ee4fc4ebe2ba4751c9e4874a589c Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Thu, 22 Aug 2024 09:18:14 +0300
Subject: [PATCH 068/144] Minor fix (#2275)
---
app/assets/appfilter.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index 1675e806208..0f59ec1b1aa 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -2165,7 +2165,6 @@
-
@@ -7352,6 +7351,7 @@
+
From 5ccd2f935f5dba5732e9ccf56f1ff54a0c21f0fa Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Fri, 23 Aug 2024 00:32:40 +0300
Subject: [PATCH 069/144] +11 links (#2277)
---
app/assets/appfilter.xml | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index 0f59ec1b1aa..3059e6e48d2 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -1539,6 +1539,7 @@
+
@@ -2565,6 +2566,7 @@
+
@@ -3701,6 +3703,7 @@
+
@@ -4390,6 +4393,7 @@
+
@@ -4416,6 +4420,7 @@
+
@@ -6131,6 +6136,7 @@
+
@@ -6650,6 +6656,7 @@
+
@@ -8327,6 +8334,7 @@
+
@@ -11174,20 +11182,21 @@
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
-
+
-
-
+
+
@@ -11851,6 +11860,7 @@
+
@@ -12335,6 +12345,7 @@
+
From eec3a99cb009b9fda5431d5ae1e4ed2fc2db9639 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 23 Aug 2024 08:27:07 +0800
Subject: [PATCH 070/144] Update Kotlin and KSP (#2276)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
build.gradle.kts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/build.gradle.kts b/build.gradle.kts
index 8de0294675f..fa51ad45f0a 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -3,10 +3,10 @@ import com.diffplug.spotless.extra.wtp.EclipseWtpFormatterStep
plugins {
id("com.android.application") version "8.5.2" apply false
- id("org.jetbrains.kotlin.android") version "2.0.10" apply false
- id("org.jetbrains.kotlin.plugin.compose") version "2.0.10"
- id("org.jetbrains.kotlin.plugin.serialization") version "2.0.10" apply false
- id("com.google.devtools.ksp") version "2.0.10-1.0.24" apply false
+ id("org.jetbrains.kotlin.android") version "2.0.20" apply false
+ id("org.jetbrains.kotlin.plugin.compose") version "2.0.20"
+ id("org.jetbrains.kotlin.plugin.serialization") version "2.0.20" apply false
+ id("com.google.devtools.ksp") version "2.0.20-1.0.24" apply false
id("com.google.dagger.hilt.android") version "2.52" apply false
id("app.cash.licensee") version "1.11.0" apply false
id("com.diffplug.spotless") version "6.25.0" apply false
From c542e1253c71bb2fb0f542b0837eeb8adf13f207 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Fri, 23 Aug 2024 11:32:34 +0800
Subject: [PATCH 071/144] Use singleton for handling prefs
---
.../lawnicons/di/UserTipsRepositoryModule.kt | 22 ------
.../lawnicons/repository/PreferenceManager.kt | 72 +++++++++++++++++++
.../repository/UserTipsRepository.kt | 27 -------
.../ui/components/home/HomeBottomBar.kt | 4 --
.../ui/components/home/IconRequestFAB.kt | 46 ++++++------
.../lawnicons/ui/destination/Home.kt | 3 +-
.../lawnicons/viewmodel/LawniconsViewModel.kt | 11 ---
7 files changed, 98 insertions(+), 87 deletions(-)
delete mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/di/UserTipsRepositoryModule.kt
create mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
delete mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/repository/UserTipsRepository.kt
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/di/UserTipsRepositoryModule.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/di/UserTipsRepositoryModule.kt
deleted file mode 100644
index f747c66eb09..00000000000
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/di/UserTipsRepositoryModule.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package app.lawnchair.lawnicons.di
-
-import android.app.Application
-import android.content.Context
-import app.lawnchair.lawnicons.repository.UserTipsRepository
-import app.lawnchair.lawnicons.repository.UserTipsRepositoryImpl
-import dagger.Module
-import dagger.Provides
-import dagger.hilt.InstallIn
-import dagger.hilt.components.SingletonComponent
-import javax.inject.Singleton
-
-@Module
-@InstallIn(SingletonComponent::class)
-object UserTipsRepositoryModule {
-
- @Provides
- @Singleton
- fun provideIconRepository(application: Application): UserTipsRepository = UserTipsRepositoryImpl(
- application.getSharedPreferences("app_prefs", Context.MODE_PRIVATE),
- )
-}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
new file mode 100644
index 00000000000..beb6e77c7ae
--- /dev/null
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
@@ -0,0 +1,72 @@
+package app.lawnchair.lawnicons.repository
+
+import android.content.Context
+import android.content.SharedPreferences
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.produceState
+import androidx.compose.ui.platform.LocalContext
+
+/**
+ * A class that abstracts the functionality of SharedPreferences
+ * @param prefs The SharedPreferences instance to use
+ */
+abstract class BasePreferenceManager(
+ private val prefs: SharedPreferences,
+) {
+ private val editor = prefs.edit()
+
+ /**
+ * A class that represents a boolean preference
+ * @param key The key of the preference
+ * @param defaultValue The default value of the preference
+ */
+ inner class BoolPref(
+ val key: String,
+ private val defaultValue: Boolean,
+ ) {
+ fun get() = prefs.getBoolean(key, defaultValue)
+ fun set(value: Boolean) = editor.putBoolean(key, value).apply()
+
+ @Composable
+ fun asState(): State {
+ return produceState(initialValue = get(), this) {
+ val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, changedKey ->
+ if (changedKey == key) {
+ value = get() // Update the state value when the preference changes
+ }
+ }
+ prefs.registerOnSharedPreferenceChangeListener(listener)
+ }
+ }
+ }
+}
+
+/**
+ * Provides a class to handle Lawnicons preferences
+ */
+class PreferenceManager private constructor(
+ prefs: SharedPreferences,
+) : BasePreferenceManager(prefs) {
+
+ val showRequestTooltip = BoolPref("icon_request_button_clicked", true)
+
+ companion object {
+ @Volatile
+ private var instance: PreferenceManager? = null
+
+ /**
+ * Returns a singleton instance of PreferenceManager
+ */
+ fun getInstance(context: Context): PreferenceManager {
+ return instance ?: synchronized(this) {
+ instance ?: PreferenceManager(
+ context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE),
+ ).also { instance = it }
+ }
+ }
+ }
+}
+
+@Composable
+fun preferenceManager(context: Context = LocalContext.current) = PreferenceManager.getInstance(context)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/UserTipsRepository.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/UserTipsRepository.kt
deleted file mode 100644
index 2667e883bb3..00000000000
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/UserTipsRepository.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package app.lawnchair.lawnicons.repository
-
-import android.content.SharedPreferences
-import javax.inject.Inject
-
-// TODO: Add additional tips
-interface UserTipsRepository {
- fun hasClickedIconRequestButton(): Boolean
- fun onIconRequestButtonClicked()
-
- fun clearTips()
-}
-
-class UserTipsRepositoryImpl @Inject constructor(private val prefs: SharedPreferences) : UserTipsRepository {
-
- companion object {
- const val ICON_REQUEST_BUTTON_CLICKED = "icon_request_button_clicked"
- }
-
- override fun hasClickedIconRequestButton(): Boolean = prefs.get(ICON_REQUEST_BUTTON_CLICKED)
- override fun onIconRequestButtonClicked() = prefs.set(ICON_REQUEST_BUTTON_CLICKED, true)
-
- override fun clearTips() = prefs.edit().clear().apply()
-}
-
-fun SharedPreferences.get(key: String): Boolean = getBoolean(key, false)
-fun SharedPreferences.set(key: String, value: Boolean) = edit().putBoolean(key, value).apply()
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeBottomBar.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeBottomBar.kt
index 623dc18e200..28e7cb023ae 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeBottomBar.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeBottomBar.kt
@@ -35,8 +35,6 @@ fun HomeBottomBar(
snackbarHostState: SnackbarHostState,
onNavigate: () -> Unit,
onExpandSearch: () -> Unit,
- isIconRequestClicked: Boolean,
- onIconRequestClick: () -> Unit,
modifier: Modifier = Modifier,
) {
BottomAppBar(
@@ -63,8 +61,6 @@ fun HomeBottomBar(
IconRequestIconButton(
iconRequestModel = iconRequestModel,
snackbarHostState = snackbarHostState,
- isIconRequestClicked = isIconRequestClicked,
- onClick = onIconRequestClick,
)
SimpleTooltipBox(
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
index 1e922a6e064..c7e13efe88b 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
@@ -52,6 +52,7 @@ import androidx.compose.ui.unit.dp
import app.lawnchair.lawnicons.R
import app.lawnchair.lawnicons.model.IconRequest
import app.lawnchair.lawnicons.model.IconRequestModel
+import app.lawnchair.lawnicons.repository.preferenceManager
import app.lawnchair.lawnicons.ui.components.core.Card
import app.lawnchair.lawnicons.ui.util.Constants
import app.lawnchair.lawnicons.ui.util.isScrollingUp
@@ -91,18 +92,18 @@ fun IconRequestFAB(
@Composable
fun IconRequestIconButton(
- isIconRequestClicked: Boolean,
snackbarHostState: SnackbarHostState,
iconRequestModel: IconRequestModel?,
- onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
+ val prefs = preferenceManager()
+
RequestHandler(
iconRequestModel = iconRequestModel,
snackbarHostState = snackbarHostState,
- onClick = onClick,
+ onClick = { prefs.showRequestTooltip.set(false) },
) { interactionSource ->
- IconRequestTooltip(isIconRequestClicked) {
+ IconRequestTooltip(prefs.showRequestTooltip.asState().value) {
IconButton(
onClick = {},
interactionSource = interactionSource,
@@ -121,34 +122,37 @@ fun IconRequestIconButton(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun IconRequestTooltip(
- isButtonClicked: Boolean,
+ showTooltip: Boolean,
content: @Composable (() -> Unit),
) {
val state = rememberTooltipState(
initialIsVisible = true,
isPersistent = true,
)
- val hideTooltip = remember { isButtonClicked }
- LaunchedEffect(hideTooltip) {
- if (hideTooltip) {
+ LaunchedEffect(showTooltip) {
+ if (!showTooltip) {
state.dismiss()
}
}
- TooltipBox(
- positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
- tooltip = {
- PlainTooltip(
- containerColor = MaterialTheme.colorScheme.primaryContainer,
- contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
- caretSize = DpSize(16.dp, 8.dp),
- ) {
- Text("Request missing icons here")
- }
- },
- state = state,
- ) {
+ if (showTooltip) {
+ TooltipBox(
+ positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
+ tooltip = {
+ PlainTooltip(
+ containerColor = MaterialTheme.colorScheme.primaryContainer,
+ contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ caretSize = DpSize(16.dp, 8.dp),
+ ) {
+ Text("Request missing icons here")
+ }
+ },
+ state = state,
+ ) {
+ content()
+ }
+ } else {
content()
}
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
index 3e98e37a917..017ab6ff09a 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
@@ -20,6 +20,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import app.lawnchair.lawnicons.model.IconInfo
import app.lawnchair.lawnicons.model.SearchMode
+import app.lawnchair.lawnicons.repository.preferenceManager
import app.lawnchair.lawnicons.ui.components.home.HomeBottomBar
import app.lawnchair.lawnicons.ui.components.home.HomeTopBar
import app.lawnchair.lawnicons.ui.components.home.HomeTopBarUiState
@@ -90,8 +91,6 @@ fun Home(
snackbarHostState = snackbarHostState,
onNavigate = onNavigate,
onExpandSearch = { expandSearch = true },
- isIconRequestClicked = isIconRequestButtonClicked,
- onIconRequestClick = ::onIconRequestButtonClicked,
)
}
},
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt
index 69fbd2e5f57..b6d23e9fefc 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt
@@ -7,7 +7,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.lawnchair.lawnicons.model.SearchMode
import app.lawnchair.lawnicons.repository.IconRepository
-import app.lawnchair.lawnicons.repository.UserTipsRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.launch
@@ -15,7 +14,6 @@ import kotlinx.coroutines.launch
@HiltViewModel
class LawniconsViewModel @Inject constructor(
private val iconRepository: IconRepository,
- private val userTipsRepository: UserTipsRepository,
) :
ViewModel() {
@JvmField
@@ -27,9 +25,6 @@ class LawniconsViewModel @Inject constructor(
@JvmField
val iconRequestModel = iconRepository.iconRequestList
- @JvmField
- val isIconRequestButtonClicked = userTipsRepository.hasClickedIconRequestButton()
-
var expandSearch by mutableStateOf(false)
private var _searchMode by mutableStateOf(SearchMode.LABEL)
@@ -61,10 +56,4 @@ class LawniconsViewModel @Inject constructor(
iconRepository.clearSearch()
}
}
-
- fun onIconRequestButtonClicked() {
- if (!userTipsRepository.hasClickedIconRequestButton()) {
- userTipsRepository.onIconRequestButtonClicked()
- }
- }
}
From 9353ecaa4248e692851e122c588054a927df2830 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Fri, 23 Aug 2024 12:31:22 +0800
Subject: [PATCH 072/144] Use snackbar instead of tooltip for first launch
---
.../lawnicons/repository/PreferenceManager.kt | 5 +-
.../ui/components/home/IconRequestFAB.kt | 208 +++++++++---------
app/src/main/res/values/strings.xml | 1 +
3 files changed, 112 insertions(+), 102 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
index beb6e77c7ae..9a9e7a2a448 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
@@ -28,6 +28,8 @@ abstract class BasePreferenceManager(
fun get() = prefs.getBoolean(key, defaultValue)
fun set(value: Boolean) = editor.putBoolean(key, value).apply()
+ fun onChange() = set(!get())
+
@Composable
fun asState(): State {
return produceState(initialValue = get(), this) {
@@ -48,8 +50,7 @@ abstract class BasePreferenceManager(
class PreferenceManager private constructor(
prefs: SharedPreferences,
) : BasePreferenceManager(prefs) {
-
- val showRequestTooltip = BoolPref("icon_request_button_clicked", true)
+ val showFirstLaunchSnackbar = BoolPref("show_first_launch_snackbar", true)
companion object {
@Volatile
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
index c7e13efe88b..3ce7213b7e8 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
@@ -22,32 +22,30 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
-import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
-import androidx.compose.material3.PlainTooltip
+import androidx.compose.material3.SheetState
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
-import androidx.compose.material3.TooltipBox
-import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.rememberModalBottomSheetState
-import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalViewConfiguration
+import androidx.compose.ui.platform.ViewConfiguration
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
-import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import app.lawnchair.lawnicons.R
import app.lawnchair.lawnicons.model.IconRequest
@@ -68,8 +66,9 @@ fun IconRequestFAB(
snackbarHostState: SnackbarHostState,
modifier: Modifier = Modifier,
) {
+ val list = iconRequestModel?.list ?: emptyList()
RequestHandler(
- iconRequestModel = iconRequestModel,
+ iconRequestList = list,
snackbarHostState = snackbarHostState,
) { interactionSource ->
ExtendedFloatingActionButton(
@@ -96,81 +95,22 @@ fun IconRequestIconButton(
iconRequestModel: IconRequestModel?,
modifier: Modifier = Modifier,
) {
- val prefs = preferenceManager()
+ val list = iconRequestModel?.list ?: emptyList()
RequestHandler(
- iconRequestModel = iconRequestModel,
+ iconRequestList = list,
snackbarHostState = snackbarHostState,
- onClick = { prefs.showRequestTooltip.set(false) },
) { interactionSource ->
- IconRequestTooltip(prefs.showRequestTooltip.asState().value) {
- IconButton(
- onClick = {},
- interactionSource = interactionSource,
- modifier = modifier,
- ) {
- Icon(
- painter = painterResource(id = R.drawable.icon_request_app),
- contentDescription = stringResource(R.string.request_icons),
- modifier = Modifier.requiredSize(24.dp),
- )
- }
- }
- }
-}
-
-@OptIn(ExperimentalMaterial3Api::class)
-@Composable
-private fun IconRequestTooltip(
- showTooltip: Boolean,
- content: @Composable (() -> Unit),
-) {
- val state = rememberTooltipState(
- initialIsVisible = true,
- isPersistent = true,
- )
-
- LaunchedEffect(showTooltip) {
- if (!showTooltip) {
- state.dismiss()
- }
- }
-
- if (showTooltip) {
- TooltipBox(
- positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
- tooltip = {
- PlainTooltip(
- containerColor = MaterialTheme.colorScheme.primaryContainer,
- contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
- caretSize = DpSize(16.dp, 8.dp),
- ) {
- Text("Request missing icons here")
- }
- },
- state = state,
- ) {
- content()
- }
- } else {
- content()
- }
-}
-
-@Composable
-fun RequestHandler(
- iconRequestModel: IconRequestModel?,
- snackbarHostState: SnackbarHostState,
- onClick: () -> Unit = {},
- content: @Composable ((interactionSource: MutableInteractionSource) -> Unit),
-) {
- if (iconRequestModel != null) {
- RequestHandler(
- iconRequestList = iconRequestModel.list,
- snackbarHostState = snackbarHostState,
- onClick = onClick,
+ IconButton(
+ onClick = {},
+ interactionSource = interactionSource,
+ modifier = modifier,
) {
- content(it)
+ Icon(
+ painter = painterResource(id = R.drawable.icon_request_app),
+ contentDescription = stringResource(R.string.request_icons),
+ modifier = Modifier.requiredSize(24.dp),
+ )
}
}
}
@@ -180,39 +120,86 @@ fun RequestHandler(
fun RequestHandler(
iconRequestList: List,
snackbarHostState: SnackbarHostState,
- onClick: () -> Unit,
content: @Composable ((interactionSource: MutableInteractionSource) -> Unit),
) {
+ val prefs = preferenceManager()
+ val showFirstLaunchSnackbar by prefs.showFirstLaunchSnackbar.asState()
val context = LocalContext.current
- val viewConfiguration = LocalViewConfiguration.current
-
- val onClickEffect = rememberUpdatedState(onClick)
val requestList = formatIconRequestList(iconRequestList)
val encodedRequestList = buildForm(requestList.replace("\n", "%20"))
+ val directLinkEnabled = encodedRequestList.length < Constants.DIRECT_LINK_MAX_LENGTH
- val sheetExpanded = remember { mutableStateOf(false) }
+ var sheetExpanded by remember { mutableStateOf(false) }
val sheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true,
)
- val coroutineScope = rememberCoroutineScope()
+ val scope = rememberCoroutineScope()
val interactionSource = remember { MutableInteractionSource() }
- val directLinkEnabled = encodedRequestList.length < Constants.DIRECT_LINK_MAX_LENGTH
+ HandleTouchInteractions(
+ interactionSource = interactionSource,
+ viewConfiguration = LocalViewConfiguration.current,
+ context = context,
+ coroutineScope = scope,
+ onExpandSheet = { sheetExpanded = it },
+ sheetState = sheetState,
+ iconRequestList = iconRequestList,
+ directLinkEnabled = directLinkEnabled,
+ encodedRequestList = encodedRequestList,
+ requestList = requestList,
+ snackbarHostState = snackbarHostState,
+ )
+
+ content(interactionSource)
+
+ if (showFirstLaunchSnackbar && iconRequestList.isNotEmpty()) {
+ openSnackbarFirstLaunchContent(
+ context,
+ scope,
+ prefs.showFirstLaunchSnackbar::onChange,
+ snackbarHostState,
+ )
+ }
+ AnimatedVisibility(visible = sheetExpanded) {
+ ModalBottomSheet(
+ onDismissRequest = { sheetExpanded = false },
+ sheetState = sheetState,
+ ) {
+ IconRequestSheet(requestList, context)
+ }
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+private fun HandleTouchInteractions(
+ interactionSource: MutableInteractionSource,
+ viewConfiguration: ViewConfiguration,
+ context: Context,
+ coroutineScope: CoroutineScope,
+ onExpandSheet: (Boolean) -> Unit,
+ sheetState: SheetState,
+ iconRequestList: List,
+ directLinkEnabled: Boolean,
+ requestList: String,
+ encodedRequestList: String,
+ snackbarHostState: SnackbarHostState,
+) {
+ val lastestOnExpandSheet by rememberUpdatedState(newValue = onExpandSheet)
LaunchedEffect(interactionSource) {
var isLongClick = false
interactionSource.interactions.collectLatest { interaction ->
when (interaction) {
is PressInteraction.Press -> {
- onClickEffect.value()
isLongClick = false
delay(viewConfiguration.longPressTimeoutMillis)
isLongClick = true
coroutineScope.launch {
- sheetExpanded.value = true
+ lastestOnExpandSheet(true)
sheetState.show()
}
}
@@ -224,7 +211,12 @@ fun RequestHandler(
} else if (directLinkEnabled) {
openLink(context, encodedRequestList)
} else {
- openSnackbarContent(context, requestList, coroutineScope, snackbarHostState)
+ openSnackbarWarningContent(
+ context,
+ requestList,
+ coroutineScope,
+ snackbarHostState,
+ )
}
}
}
@@ -235,17 +227,6 @@ fun RequestHandler(
}
}
}
-
- content(interactionSource)
-
- AnimatedVisibility(visible = sheetExpanded.value) {
- ModalBottomSheet(
- onDismissRequest = { sheetExpanded.value = false },
- sheetState = sheetState,
- ) {
- IconRequestSheet(requestList, context)
- }
- }
}
@Composable
@@ -294,7 +275,35 @@ private fun copyTextToClipboard(context: Context, text: String) {
clipboard.setPrimaryClip(clip)
}
-private fun openSnackbarContent(
+private fun openSnackbarFirstLaunchContent(
+ context: Context,
+ coroutineScope: CoroutineScope,
+ onActionPerformed: () -> Unit,
+ snackbarHostState: SnackbarHostState,
+) {
+ coroutineScope.launch {
+ val result = snackbarHostState
+ .showSnackbar(
+ message = context.getString(R.string.you_have_missing_icons),
+ actionLabel = context.getString(R.string.request_icons),
+ withDismissAction = true,
+ duration = SnackbarDuration.Indefinite,
+ )
+ when (result) {
+ SnackbarResult.ActionPerformed -> {
+ onActionPerformed()
+ openLink(context, Constants.ICON_REQUEST_FORM)
+ }
+
+ SnackbarResult.Dismissed -> {
+ onActionPerformed()
+ snackbarHostState.currentSnackbarData?.dismiss()
+ }
+ }
+ }
+}
+
+private fun openSnackbarWarningContent(
context: Context,
list: String,
coroutineScope: CoroutineScope,
@@ -311,7 +320,6 @@ private fun openSnackbarContent(
)
when (result) {
SnackbarResult.ActionPerformed -> {
- /* Handle snackbar action performed */
openLink(context, Constants.ICON_REQUEST_FORM)
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5633c4de3ee..d02c191f394 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -84,4 +84,5 @@
Copied icon request details to clipboard. To request them, submit the details into the form.
Open form
+ You have missing icons
From b589f24054f06f9fd20d4f4f9a6762058404d016 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Fri, 23 Aug 2024 12:36:48 +0800
Subject: [PATCH 073/144] Update placeholder UI
---
.../home/search/PlaceholderSearchBar.kt | 7 ++----
.../lawnicons/ui/destination/Home.kt | 23 +++++++++++++++----
2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/PlaceholderSearchBar.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/PlaceholderSearchBar.kt
index dd2bcfbaf77..e849693d127 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/PlaceholderSearchBar.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/PlaceholderSearchBar.kt
@@ -22,7 +22,6 @@ import app.lawnchair.lawnicons.ui.util.PreviewLawnicons
@Composable
fun PlaceholderSearchBar(
- isExpandedScreen: Boolean,
modifier: Modifier = Modifier,
) {
Column(
@@ -38,9 +37,7 @@ fun PlaceholderSearchBar(
content = {},
contentAlignment = Alignment.TopCenter,
modifier = Modifier
- .then(
- if (isExpandedScreen) Modifier.width(360.dp) else Modifier,
- )
+ .width(360.dp)
.zIndex(1f)
.statusBarsPadding()
.padding(top = 8.dp)
@@ -60,6 +57,6 @@ fun PlaceholderSearchBar(
@Composable
private fun PlaceholderSearchBarPreview() {
LawniconsTheme {
- PlaceholderSearchBar(false)
+ PlaceholderSearchBar()
}
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
index 017ab6ff09a..7fcf0b211ae 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
@@ -3,7 +3,12 @@ package app.lawnchair.lawnicons.ui.destination
import android.annotation.SuppressLint
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
+import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
@@ -13,6 +18,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.platform.LocalContext
@@ -20,7 +26,6 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import app.lawnchair.lawnicons.model.IconInfo
import app.lawnchair.lawnicons.model.SearchMode
-import app.lawnchair.lawnicons.repository.preferenceManager
import app.lawnchair.lawnicons.ui.components.home.HomeBottomBar
import app.lawnchair.lawnicons.ui.components.home.HomeTopBar
import app.lawnchair.lawnicons.ui.components.home.HomeTopBarUiState
@@ -36,7 +41,7 @@ import app.lawnchair.lawnicons.viewmodel.LawniconsViewModel
import kotlinx.collections.immutable.toImmutableList
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
-@OptIn(ExperimentalFoundationApi::class)
+@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@Composable
fun Home(
onNavigate: () -> Unit,
@@ -116,9 +121,17 @@ fun Home(
)
}
} else {
- PlaceholderSearchBar(
- isExpandedScreen = isExpandedScreen,
- )
+ if (isExpandedScreen) {
+ PlaceholderSearchBar()
+ } else {
+ Column(
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.fillMaxSize(),
+ ) {
+ CircularProgressIndicator()
+ }
+ }
}
}
LaunchedEffect(expandSearch) {
From b4d766d9332076783ba560fffc9fc66eb968e9c5 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Fri, 23 Aug 2024 12:37:01 +0800
Subject: [PATCH 074/144] Fix padding
---
.../lawnicons/ui/components/home/IconPreviewGrid.kt | 2 +-
.../lawnicons/ui/components/home/search/SearchContents.kt | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
index 3f755301961..7418990dbd1 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
@@ -71,7 +71,7 @@ fun IconPreviewGrid(
.fillMaxWidth()
.statusBarsPadding()
.then(
- if (isExpandedScreen) Modifier.padding(top = 26.dp) else Modifier,
+ if (isExpandedScreen) Modifier.padding(top = 26.dp) else Modifier.padding(bottom = 80.dp),
),
state = gridState,
settings = ScrollbarSettings(
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
index 702e28652c0..c2f05d47838 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
@@ -123,6 +123,7 @@ fun SearchContents(
1 -> {
IconInfoListItem(iconInfo)
}
+
0 -> {
Box(
modifier = Modifier
@@ -145,7 +146,7 @@ fun SearchContents(
) { iconInfo ->
LazyVerticalGrid(
columns = GridCells.Adaptive(minSize = 80.dp),
- contentPadding = PaddingValues(16.dp),
+ contentPadding = PaddingValues(16.dp, 16.dp, 16.dp, 80.dp),
) {
items(
items = iconInfo,
@@ -154,7 +155,7 @@ fun SearchContents(
IconPreview(
iconInfo = it,
onSendResult = onSendResult,
- iconBackground = MaterialTheme.colorScheme.surfaceVariant,
+ iconBackground = MaterialTheme.colorScheme.surfaceContainerLow,
)
}
}
From 0bdd5d9bf297c7e7a8b2868caaa3e3ff0467d40f Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Fri, 23 Aug 2024 13:07:10 +0800
Subject: [PATCH 075/144] Simplify IconInfo
---
.../app/lawnchair/lawnicons/model/IconInfo.kt | 76 +++++++++----------
.../lawnicons/repository/IconRepository.kt | 5 +-
.../lawnchair/lawnicons/util/GetIconInfo.kt | 6 +-
3 files changed, 40 insertions(+), 47 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconInfo.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconInfo.kt
index 7d3a6351f6b..6661e3118ef 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconInfo.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconInfo.kt
@@ -21,52 +21,44 @@ data class IconInfo(
}
/**
- * A helper object for processing and manipulating collections of [IconInfo] objects,
- * including merging and splitting based on drawable names and component names.
+ * Merges a list of [IconInfo] objects, grouping them by their `drawableName` and
+ * combining the `componentNames` of icons with the same drawable name.
+ *
+ * @return A new list of [IconInfo] objects with merged component names for icons
+ * sharing the same drawable name.
*/
-object IconInfoManager {
- /**
- * Merges a list of [IconInfo] objects, grouping them by their `drawableName` and
- * combining the `componentNames` of icons with the same drawable name.
- *
- * @param iconInfoList The list of [IconInfo] objects to merge.
- * @return A new list of [IconInfo] objects with merged component names for icons
- * sharing the same drawable name.
- */
- fun mergeByDrawableName(iconInfoList: List): List {
- return iconInfoList.groupBy { it.drawableName }
- .map { (drawableName, icons) ->
- val mergedComponentNames = icons.flatMap { it.componentNames }
- IconInfo(
- componentNames = mergedComponentNames,
- drawableName = drawableName,
- id = icons.first().id,
- )
- }
- }
+fun List.mergeByDrawableName(): List {
+ return groupBy { it.drawableName }
+ .map { (drawableName, icons) ->
+ val mergedComponentNames = icons.flatMap { it.componentNames }
+ IconInfo(
+ componentNames = mergedComponentNames,
+ drawableName = drawableName,
+ id = icons.first().id,
+ )
+ }
+}
- /**
- * Splits [IconInfo] objects with multiple component names into a list where each
- * [IconInfo] object has a single component name.
- *
- * @param iconInfoList The list of [IconInfo] objects to split.
- * @return A new list of [IconInfo] objects, each with a single component name.
- */
- fun splitByComponentName(iconInfoList: List): List {
- val splitList = mutableListOf()
- for (iconInfo in iconInfoList) {
- for (nameAndComponent in iconInfo.componentNames) {
- splitList.add(
- IconInfo(
- componentNames = listOf(nameAndComponent),
- drawableName = iconInfo.drawableName,
- id = iconInfo.id,
- ),
- )
- }
+/**
+ * Splits [IconInfo] objects with multiple component names into a list where each
+ * [IconInfo] object has a single component name.
+ *
+ * @return A new list of [IconInfo] objects, each with a single component name.
+ */
+fun List.splitByComponentName(): List {
+ val splitList = mutableListOf()
+ for (iconInfo in this) {
+ for (nameAndComponent in iconInfo.componentNames) {
+ splitList.add(
+ IconInfo(
+ componentNames = listOf(nameAndComponent),
+ drawableName = iconInfo.drawableName,
+ id = iconInfo.id,
+ ),
+ )
}
- return splitList
}
+ return splitList
}
fun IconInfo.getFirstLabelAndComponent(): LabelAndComponent {
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt
index 1c18cdda2e8..c03ddb1cf28 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt
@@ -2,13 +2,13 @@ package app.lawnchair.lawnicons.repository
import android.app.Application
import app.lawnchair.lawnicons.model.IconInfo
-import app.lawnchair.lawnicons.model.IconInfoManager
import app.lawnchair.lawnicons.model.IconInfoModel
import app.lawnchair.lawnicons.model.IconRequest
import app.lawnchair.lawnicons.model.IconRequestModel
import app.lawnchair.lawnicons.model.SearchInfo
import app.lawnchair.lawnicons.model.SearchMode
import app.lawnchair.lawnicons.model.getFirstLabelAndComponent
+import app.lawnchair.lawnicons.model.splitByComponentName
import app.lawnchair.lawnicons.util.getIconInfo
import app.lawnchair.lawnicons.util.getSystemIconInfoAppfilter
import javax.inject.Inject
@@ -112,7 +112,8 @@ class IconRepositoryImpl @Inject constructor(application: Application) : IconRep
info.getFirstLabelAndComponent()
}
- val lawniconsComponents = IconInfoManager.splitByComponentName(lawniconsData)
+ val lawniconsComponents = lawniconsData
+ .splitByComponentName()
.map { it.getFirstLabelAndComponent().componentName }
.sortedBy { it.lowercase() }
.toSet()
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/util/GetIconInfo.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/util/GetIconInfo.kt
index abcd3fac554..7ea59aeb188 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/util/GetIconInfo.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/util/GetIconInfo.kt
@@ -4,13 +4,13 @@ import android.annotation.SuppressLint
import android.content.Context
import app.lawnchair.lawnicons.R
import app.lawnchair.lawnicons.model.IconInfo
-import app.lawnchair.lawnicons.model.IconInfoManager
import app.lawnchair.lawnicons.model.LabelAndComponent
+import app.lawnchair.lawnicons.model.mergeByDrawableName
import org.xmlpull.v1.XmlPullParser
@SuppressLint("DiscouragedApi")
fun Context.getIconInfo(): List {
- var iconInfo = mutableListOf()
+ val iconInfo = mutableListOf()
val componentInfoPrefixLength = "ComponentInfo{".length
@@ -61,5 +61,5 @@ fun Context.getIconInfo(): List {
e.printStackTrace()
}
- return IconInfoManager.mergeByDrawableName(iconInfo)
+ return iconInfo.mergeByDrawableName()
}
From 8522751a23592c383cbd246ec5d9f7902bc01045 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Fri, 23 Aug 2024 13:16:09 +0800
Subject: [PATCH 076/144] Fix scrollbar content
Fix #2256
---
.../ui/components/home/IconPreviewGrid.kt | 56 ++++++++++++-------
1 file changed, 35 insertions(+), 21 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
index 7418990dbd1..92c81d274b2 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
@@ -9,6 +9,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@@ -31,6 +32,8 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
@@ -60,6 +63,9 @@ fun IconPreviewGrid(
contentPadding: PaddingValues? = null,
gridState: LazyGridState = rememberLazyGridState(),
) {
+ val indexOfFirstItem = remember { derivedStateOf { gridState.firstVisibleItemIndex } }
+ val letter = iconInfo[indexOfFirstItem.value].label[0].uppercase()
+
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
@@ -81,27 +87,7 @@ fun IconPreviewGrid(
selectionMode = ScrollbarSelectionMode.Thumb,
),
indicatorContent = { _, isThumbSelected ->
- AnimatedVisibility(
- visible = isThumbSelected,
- enter = fadeIn(),
- exit = fadeOut(),
- ) {
- Box(
- modifier = Modifier
- .padding(end = 16.dp)
- .background(
- color = MaterialTheme.colorScheme.primary,
- shape = MaterialTheme.shapes.large,
- ),
- ) {
- Text(
- modifier = Modifier.padding(16.dp),
- text = "#",
- style = MaterialTheme.typography.titleMedium,
- color = MaterialTheme.colorScheme.onPrimary,
- )
- }
- }
+ ScrollbarIndicator(letter, isThumbSelected)
},
) {
val horizontalGridPadding = if (isExpandedScreen) 32.dp else 8.dp
@@ -138,6 +124,34 @@ fun IconPreviewGrid(
}
}
+@Composable
+private fun ColumnScope.ScrollbarIndicator(
+ label: String,
+ isThumbSelected: Boolean,
+) {
+ AnimatedVisibility(
+ visible = isThumbSelected,
+ enter = fadeIn(),
+ exit = fadeOut(),
+ ) {
+ Box(
+ modifier = Modifier
+ .padding(end = 16.dp)
+ .background(
+ color = MaterialTheme.colorScheme.primary,
+ shape = MaterialTheme.shapes.large,
+ ),
+ ) {
+ Text(
+ modifier = Modifier.padding(16.dp),
+ text = label,
+ style = MaterialTheme.typography.titleMedium,
+ color = MaterialTheme.colorScheme.onPrimary,
+ )
+ }
+ }
+}
+
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TopAppBar(modifier: Modifier = Modifier) {
From c974fcf8dac9993103e2b891326835f3ec2ab99d Mon Sep 17 00:00:00 2001
From: Goooler
Date: Fri, 23 Aug 2024 14:02:08 +0800
Subject: [PATCH 077/144] Group myself to infra
---
.../main/kotlin/app/lawnchair/lawnicons/ui/destination/About.kt | 2 +-
app/src/main/res/values-af-rZA/strings.xml | 1 -
app/src/main/res/values-ar-rSA/strings.xml | 1 -
app/src/main/res/values-ca-rES/strings.xml | 1 -
app/src/main/res/values-cs-rCZ/strings.xml | 1 -
app/src/main/res/values-da-rDK/strings.xml | 1 -
app/src/main/res/values-de-rDE/strings.xml | 1 -
app/src/main/res/values-el-rGR/strings.xml | 1 -
app/src/main/res/values-en-rUS/strings.xml | 1 -
app/src/main/res/values-es-rES/strings.xml | 1 -
app/src/main/res/values-fi-rFI/strings.xml | 1 -
app/src/main/res/values-fil-rPH/strings.xml | 1 -
app/src/main/res/values-fr-rFR/strings.xml | 1 -
app/src/main/res/values-hi-rIN/strings.xml | 1 -
app/src/main/res/values-hu-rHU/strings.xml | 1 -
app/src/main/res/values-in-rID/strings.xml | 1 -
app/src/main/res/values-it-rIT/strings.xml | 1 -
app/src/main/res/values-iw-rIL/strings.xml | 1 -
app/src/main/res/values-ja-rJP/strings.xml | 1 -
app/src/main/res/values-ko-rKR/strings.xml | 1 -
app/src/main/res/values-mr-rIN/strings.xml | 1 -
app/src/main/res/values-nl-rNL/strings.xml | 1 -
app/src/main/res/values-no-rNO/strings.xml | 1 -
app/src/main/res/values-pl-rPL/strings.xml | 1 -
app/src/main/res/values-pt-rBR/strings.xml | 1 -
app/src/main/res/values-pt-rPT/strings.xml | 1 -
app/src/main/res/values-ro-rRO/strings.xml | 1 -
app/src/main/res/values-ru-rRU/strings.xml | 1 -
app/src/main/res/values-sv-rSE/strings.xml | 1 -
app/src/main/res/values-tr-rTR/strings.xml | 1 -
app/src/main/res/values-uk-rUA/strings.xml | 1 -
app/src/main/res/values-vi-rVN/strings.xml | 1 -
app/src/main/res/values-zh-rCN/strings.xml | 1 -
app/src/main/res/values-zh-rTW/strings.xml | 1 -
app/src/main/res/values/strings.xml | 2 +-
35 files changed, 2 insertions(+), 35 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/About.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/About.kt
index e5ae792bf97..68a70354255 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/About.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/About.kt
@@ -93,7 +93,7 @@ private val coreContributors = listOf(
username = "Goooler",
photoUrl = "https://avatars.githubusercontent.com/u/10363352",
socialUrl = "https://androiddev.social/@Goooler",
- descriptionRes = R.string.contribution_deps,
+ descriptionRes = R.string.contribution_infra,
),
)
diff --git a/app/src/main/res/values-af-rZA/strings.xml b/app/src/main/res/values-af-rZA/strings.xml
index 680cb8e8e1c..2c96f6ec44c 100644
--- a/app/src/main/res/values-af-rZA/strings.xml
+++ b/app/src/main/res/values-af-rZA/strings.xml
@@ -33,7 +33,6 @@
Core app
Icons
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-ar-rSA/strings.xml b/app/src/main/res/values-ar-rSA/strings.xml
index e613c59d823..ef89bd8810e 100644
--- a/app/src/main/res/values-ar-rSA/strings.xml
+++ b/app/src/main/res/values-ar-rSA/strings.xml
@@ -33,7 +33,6 @@
Core app
الأيقونات
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-ca-rES/strings.xml b/app/src/main/res/values-ca-rES/strings.xml
index fda7534543c..21ae600a6da 100644
--- a/app/src/main/res/values-ca-rES/strings.xml
+++ b/app/src/main/res/values-ca-rES/strings.xml
@@ -33,7 +33,6 @@
Core app
Icones
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml
index 0e32a08e8e1..f236fefd641 100644
--- a/app/src/main/res/values-cs-rCZ/strings.xml
+++ b/app/src/main/res/values-cs-rCZ/strings.xml
@@ -33,7 +33,6 @@
Core app
Ikony
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-da-rDK/strings.xml b/app/src/main/res/values-da-rDK/strings.xml
index d8c6f75ccb5..a07187d65d6 100644
--- a/app/src/main/res/values-da-rDK/strings.xml
+++ b/app/src/main/res/values-da-rDK/strings.xml
@@ -33,7 +33,6 @@
Core app
Ikoner
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml
index f2139d339b6..c6ed397c757 100644
--- a/app/src/main/res/values-de-rDE/strings.xml
+++ b/app/src/main/res/values-de-rDE/strings.xml
@@ -33,7 +33,6 @@
Kern-App
Symbole
- Abhängigkeiten
Besonderer Dank
diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml
index bdcfc182cc9..3041ae315d7 100644
--- a/app/src/main/res/values-el-rGR/strings.xml
+++ b/app/src/main/res/values-el-rGR/strings.xml
@@ -33,7 +33,6 @@
Core app
Εικονίδια
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-en-rUS/strings.xml b/app/src/main/res/values-en-rUS/strings.xml
index 7823eaee94c..17cf6c8d98f 100644
--- a/app/src/main/res/values-en-rUS/strings.xml
+++ b/app/src/main/res/values-en-rUS/strings.xml
@@ -33,7 +33,6 @@
Core app
Icons
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml
index 419742f5126..a29653b6654 100644
--- a/app/src/main/res/values-es-rES/strings.xml
+++ b/app/src/main/res/values-es-rES/strings.xml
@@ -33,7 +33,6 @@
Core app
Iconos
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-fi-rFI/strings.xml b/app/src/main/res/values-fi-rFI/strings.xml
index 92ae1aa4582..c9fef536a95 100644
--- a/app/src/main/res/values-fi-rFI/strings.xml
+++ b/app/src/main/res/values-fi-rFI/strings.xml
@@ -33,7 +33,6 @@
Core app
Kuvakkeet
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-fil-rPH/strings.xml b/app/src/main/res/values-fil-rPH/strings.xml
index 34d46654429..c8a453a8f0f 100644
--- a/app/src/main/res/values-fil-rPH/strings.xml
+++ b/app/src/main/res/values-fil-rPH/strings.xml
@@ -33,7 +33,6 @@
Core app
Mga Icon
- Dependencies
Espesyal na pagsasalamat
diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml
index 4418dc73661..76fc6e5f4fb 100644
--- a/app/src/main/res/values-fr-rFR/strings.xml
+++ b/app/src/main/res/values-fr-rFR/strings.xml
@@ -33,7 +33,6 @@
Core app
Icônes
- Dependencies
Remerciements spéciaux
diff --git a/app/src/main/res/values-hi-rIN/strings.xml b/app/src/main/res/values-hi-rIN/strings.xml
index bdf5ded2ef3..3184fce8814 100644
--- a/app/src/main/res/values-hi-rIN/strings.xml
+++ b/app/src/main/res/values-hi-rIN/strings.xml
@@ -33,7 +33,6 @@
Core app
चिह्न
- Dependencies
विशेष धन्यवाद
diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml
index ea13a9c6a7a..ba7af2b819a 100644
--- a/app/src/main/res/values-hu-rHU/strings.xml
+++ b/app/src/main/res/values-hu-rHU/strings.xml
@@ -33,7 +33,6 @@
Core app
Ikonok
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-in-rID/strings.xml b/app/src/main/res/values-in-rID/strings.xml
index 1a1b8444c89..3f09b2b5753 100644
--- a/app/src/main/res/values-in-rID/strings.xml
+++ b/app/src/main/res/values-in-rID/strings.xml
@@ -33,7 +33,6 @@
Core app
Ikon
- Dependencies
Terima kasih Khusus
diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml
index 715511adeea..cb0f69037e7 100644
--- a/app/src/main/res/values-it-rIT/strings.xml
+++ b/app/src/main/res/values-it-rIT/strings.xml
@@ -33,7 +33,6 @@
Core app
Icone
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-iw-rIL/strings.xml b/app/src/main/res/values-iw-rIL/strings.xml
index 79c06deb07b..3181c5bbb22 100644
--- a/app/src/main/res/values-iw-rIL/strings.xml
+++ b/app/src/main/res/values-iw-rIL/strings.xml
@@ -33,7 +33,6 @@
Core app
סמלים
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml
index b1f22fed11c..f8340bc15e1 100644
--- a/app/src/main/res/values-ja-rJP/strings.xml
+++ b/app/src/main/res/values-ja-rJP/strings.xml
@@ -33,7 +33,6 @@
Core app
アイコン
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml
index bf143a3833c..89abc4a41de 100644
--- a/app/src/main/res/values-ko-rKR/strings.xml
+++ b/app/src/main/res/values-ko-rKR/strings.xml
@@ -33,7 +33,6 @@
코어 앱
아이콘
- 의존성 라이브러리
Special thanks
diff --git a/app/src/main/res/values-mr-rIN/strings.xml b/app/src/main/res/values-mr-rIN/strings.xml
index ddde439db36..f35f9398a2e 100644
--- a/app/src/main/res/values-mr-rIN/strings.xml
+++ b/app/src/main/res/values-mr-rIN/strings.xml
@@ -33,7 +33,6 @@
Core app
चिन्हे
- Dependencies
विशेष धन्यवाद
diff --git a/app/src/main/res/values-nl-rNL/strings.xml b/app/src/main/res/values-nl-rNL/strings.xml
index ed7f5e8254d..67620cfd5dd 100644
--- a/app/src/main/res/values-nl-rNL/strings.xml
+++ b/app/src/main/res/values-nl-rNL/strings.xml
@@ -33,7 +33,6 @@
Core app
Pictogrammen
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-no-rNO/strings.xml b/app/src/main/res/values-no-rNO/strings.xml
index bb49477c568..bd33741642e 100644
--- a/app/src/main/res/values-no-rNO/strings.xml
+++ b/app/src/main/res/values-no-rNO/strings.xml
@@ -33,7 +33,6 @@
Core app
Ikoner
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml
index 8c515dfff7a..d5fe76ffd3f 100644
--- a/app/src/main/res/values-pl-rPL/strings.xml
+++ b/app/src/main/res/values-pl-rPL/strings.xml
@@ -33,7 +33,6 @@
Core app
Ikony
- Dependencies
Specjalne podziękowania
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 09a4d4bf363..fb2e7ac9e09 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -33,7 +33,6 @@
Core app
Ícones
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index 09a4d4bf363..fb2e7ac9e09 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -33,7 +33,6 @@
Core app
Ícones
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml
index 6ab1eb1b78c..3b950f5c352 100644
--- a/app/src/main/res/values-ro-rRO/strings.xml
+++ b/app/src/main/res/values-ro-rRO/strings.xml
@@ -33,7 +33,6 @@
Core app
Pictograme
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml
index 624da4179d8..038759f7b9a 100644
--- a/app/src/main/res/values-ru-rRU/strings.xml
+++ b/app/src/main/res/values-ru-rRU/strings.xml
@@ -33,7 +33,6 @@
Core app
Иконки
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml
index 0be8e30f06b..69e728926d2 100644
--- a/app/src/main/res/values-sv-rSE/strings.xml
+++ b/app/src/main/res/values-sv-rSE/strings.xml
@@ -33,7 +33,6 @@
Core app
Ikoner
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml
index b0178be1bf8..1f3cb6fa825 100644
--- a/app/src/main/res/values-tr-rTR/strings.xml
+++ b/app/src/main/res/values-tr-rTR/strings.xml
@@ -33,7 +33,6 @@
Core app
Resimleyici
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-uk-rUA/strings.xml b/app/src/main/res/values-uk-rUA/strings.xml
index de18cdc6fe3..10ee5b370e2 100644
--- a/app/src/main/res/values-uk-rUA/strings.xml
+++ b/app/src/main/res/values-uk-rUA/strings.xml
@@ -33,7 +33,6 @@
Головний додаток
Значки
- Залежності
Особлива подяка
diff --git a/app/src/main/res/values-vi-rVN/strings.xml b/app/src/main/res/values-vi-rVN/strings.xml
index d74e329d5a2..d72618aabcc 100644
--- a/app/src/main/res/values-vi-rVN/strings.xml
+++ b/app/src/main/res/values-vi-rVN/strings.xml
@@ -33,7 +33,6 @@
Core app
Biểu tượng
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 5351f587b8b..cd45165288a 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -33,7 +33,6 @@
Core app
图标
- Dependencies
Special thanks
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 46033a92969..49ef20d6629 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -33,7 +33,6 @@
Core app
圖示
- Dependencies
Special thanks
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d02c191f394..19bdf595c38 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -45,7 +45,7 @@
Core app
Icons
- Dependencies
+ Infrastructure
From fc2f199608372dbe31758e618bdaa6996a3e421e Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Fri, 23 Aug 2024 14:44:06 +0800
Subject: [PATCH 078/144] Improve snackbar behavior
---
.../ui/components/home/IconRequestFAB.kt | 66 +++++++++++--------
app/src/main/res/values/strings.xml | 3 +-
2 files changed, 42 insertions(+), 27 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
index 3ce7213b7e8..06d88d6c2cd 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
@@ -188,6 +188,7 @@ private fun HandleTouchInteractions(
encodedRequestList: String,
snackbarHostState: SnackbarHostState,
) {
+ val prefs = preferenceManager()
val lastestOnExpandSheet by rememberUpdatedState(newValue = onExpandSheet)
LaunchedEffect(interactionSource) {
var isLongClick = false
@@ -206,18 +207,16 @@ private fun HandleTouchInteractions(
is PressInteraction.Release -> {
if (!isLongClick) {
- if (iconRequestList.isEmpty()) {
- openLink(context, Constants.ICON_REQUEST_FORM)
- } else if (directLinkEnabled) {
- openLink(context, encodedRequestList)
- } else {
- openSnackbarWarningContent(
- context,
- requestList,
- coroutineScope,
- snackbarHostState,
- )
- }
+ prefs.showFirstLaunchSnackbar.set(false)
+ handleRequestClick(
+ iconRequestList,
+ context,
+ directLinkEnabled,
+ encodedRequestList,
+ requestList,
+ coroutineScope,
+ snackbarHostState,
+ )
}
}
@@ -275,6 +274,30 @@ private fun copyTextToClipboard(context: Context, text: String) {
clipboard.setPrimaryClip(clip)
}
+
+private fun handleRequestClick(
+ iconRequestList: List,
+ context: Context,
+ directLinkEnabled: Boolean,
+ encodedRequestList: String,
+ requestList: String,
+ coroutineScope: CoroutineScope,
+ snackbarHostState: SnackbarHostState,
+) {
+ if (iconRequestList.isEmpty()) {
+ openLink(context, Constants.ICON_REQUEST_FORM)
+ } else if (directLinkEnabled) {
+ openLink(context, encodedRequestList)
+ } else {
+ openSnackbarWarningContent(
+ context,
+ requestList,
+ coroutineScope,
+ snackbarHostState,
+ )
+ }
+}
+
private fun openSnackbarFirstLaunchContent(
context: Context,
coroutineScope: CoroutineScope,
@@ -284,21 +307,12 @@ private fun openSnackbarFirstLaunchContent(
coroutineScope.launch {
val result = snackbarHostState
.showSnackbar(
- message = context.getString(R.string.you_have_missing_icons),
- actionLabel = context.getString(R.string.request_icons),
- withDismissAction = true,
- duration = SnackbarDuration.Indefinite,
+ message = context.getString(R.string.snackbar_request_icons_hint),
+ duration = SnackbarDuration.Long,
)
- when (result) {
- SnackbarResult.ActionPerformed -> {
- onActionPerformed()
- openLink(context, Constants.ICON_REQUEST_FORM)
- }
-
- SnackbarResult.Dismissed -> {
- onActionPerformed()
- snackbarHostState.currentSnackbarData?.dismiss()
- }
+ if (result == SnackbarResult.Dismissed) {
+ onActionPerformed()
+ snackbarHostState.currentSnackbarData?.dismiss()
}
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 19bdf595c38..3f3ff0e25c4 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -82,7 +82,8 @@
Copied text
+ Request missing icons from the bottom bar
+
Copied icon request details to clipboard. To request them, submit the details into the form.
Open form
- You have missing icons
From 83df10f0ec90334f71d0619cb03c2f68ff80ef46 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Fri, 23 Aug 2024 14:48:53 +0800
Subject: [PATCH 079/144] Fix style
---
.../app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt | 1 -
1 file changed, 1 deletion(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
index 06d88d6c2cd..8e3cdee83b1 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
@@ -274,7 +274,6 @@ private fun copyTextToClipboard(context: Context, text: String) {
clipboard.setPrimaryClip(clip)
}
-
private fun handleRequestClick(
iconRequestList: List,
context: Context,
From 3ded652477c6aaee11a4b96ac8ce7032bc538507 Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Fri, 23 Aug 2024 16:40:07 +0300
Subject: [PATCH 080/144] Clarified the process of adding and linking icons
(#2282)
* Clarified the process of adding and linking icons
* Update CONTRIBUTING.md
---
CONTRIBUTING.md | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 52513979e45..06c3dc6cfa1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -123,31 +123,35 @@ Correct
```
## Adding an icon to Lawnicons
-Here's how to add an icon to Lawnicons:
-
### Prerequisites
-* Your icon in the SVG format, adhering to the [above guidelines](#contributing-icons). The filename must use snake case (e.g. `files_by_google.svg`).
-* The package and activity name of the app.
+* A fork of the Lawnicons repository;
+* Your icon in the SVG format, adhering to the [above guidelines](#contributing-icons). The filename must use snake case (e.g. `spck_editor.svg`).
+* The package and activity name of the app;
### Via `icontool.py`
-Please check the [icon tool guide](/docs/icontool_guide.md) for more information.
+Please check [the icon tool guide](/docs/icontool_guide.md) for more information.
### Via manual process
-1. Add the ready SVG to the `svgs` directory.
+1. Add the ready SVG to the `svgs` directory. If you want to add a link to an existing SVG, you will need its name.
-1. Add a new line to `app/assets/appfilter.xml` (in alphabetical order, by the `name` attribute), and map the new icon to a package name and app's activity. For example:
+2. Add a new line to `app/assets/appfilter.xml` (in alphabetical order, by the `name` attribute), and map the new icon to a package name and app's activity.
+ **Example**
+ - the app name: `Spck Editor`;
+ - the svg (drawable) name: `spck_editor`;
+ - the package and activity of the app: `io.spck/io.spck.EditorActivity`.
+
+ **The new line**
```xml
-
+
```
- A general template is as follows:
-
+ **General template**
```xml
```
-1. Done! You're ready to open a pull request. Please set `develop` as the base branch.
+4. Done! You're ready to open a pull request. Please set `develop` as the base branch.
## Finding the package and activity name of an app
@@ -158,8 +162,8 @@ Please check the [icon tool guide](/docs/icontool_guide.md) for more information
### Using `adb`
1. Connect your Android device or emulator to your laptop/desktop PC that has `adb` installed (see [this tutorial](https://www.xda-developers.com/install-adb-windows-macos-linux/) for more information) and open the app whose details you want to inspect, e.g. Telegram.
-1. Open a new Command Prompt or Terminal window and input `adb devices`.
-1. Finally, type the below-given command to get the information about the currently open application.
+2. Open a new Command Prompt or Terminal window and input `adb devices`.
+3. Finally, type the below-given command to get the information about the currently open application.
**For Mac or Linux**:
From be66330b688912215143409a75d4d9a9ba571b6d Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Tue, 27 Aug 2024 16:06:36 +0300
Subject: [PATCH 081/144] Updating the self-review checklist 2 (#2286)
---
.github/icon_checklist.md | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/.github/icon_checklist.md b/.github/icon_checklist.md
index 64b8cb378d3..8059999f6d6 100644
--- a/.github/icon_checklist.md
+++ b/.github/icon_checklist.md
@@ -6,21 +6,21 @@ While waiting for a review from our team, you can do a self-review to ensure tha
1. Canvas: `192×192px`.
2. Non-square icons: the long side of the icons should be `160px`.
3. Square icons: `154×154px`.
-- [ ] Done
+- [ ] Approved by the Lawnicons reviewer
### Color, stroke width and rounding
-1. Color: black `#000`.
+1. Color: non-transparent black `#000`.
2. No fill. Base stroke width: `12px`. `14px`, `10px`, `8px` — depending on the shape of the icons. `6px` — for fine details.
3. Rounded ends and joins. 90° corners are rounded by `6-32px`.
-- [ ] Done
+- [ ] Approved by the Lawnicons reviewer
### Naming
1. Names should match the official app name and contain no additional text.
2. If the first `3` characters of the app name contain letters not from the English alphabet, then add a localized (or transliterated) name via `~~`. Example: `京东 ~~ JD`.
3. The names of the drawables should repeat the names of the apps if nothing prevents it.
-- [ ] Done
+- [ ] Approved by the Lawnicons reviewer
### Quality
1. Ensure that icons are easily recognizable.
2. Align icons to [the visual center](https://crazybitsstudios.com/another-way-of-aligning-elements-when-creating-icons) as much as possible within the guidelines. The visual center is where your icon looks and feels centered.
3. Avoid noticable black spots by reducing the stroke width or simplifying the icons.
4. Avoid close distances between strokes. The icons on the phone screen will be smaller, so the small distances between the strokes will stick together.
5. Avoid drastic changes in stroke widths. When the strokes next to each other differ in width by 4px or more, the icon will look sloppy.
-- [ ] Done
+- [ ] Approved by the Lawnicons reviewer
From b9c4f8ab4cf0c5372cb62f4a63c2776368353fd6 Mon Sep 17 00:00:00 2001
From: 92 <169070113+I21b@users.noreply.github.com>
Date: Wed, 28 Aug 2024 03:49:45 +0900
Subject: [PATCH 082/144] +3 icons (#2279)
* +3 icons
* minor fix
custom_uploader svg
---
app/assets/appfilter.xml | 3 +++
svgs/cuberite.svg | 3 +++
svgs/custom_uploader.svg | 3 +++
svgs/look4sat.svg | 3 +++
4 files changed, 12 insertions(+)
create mode 100644 svgs/cuberite.svg
create mode 100644 svgs/custom_uploader.svg
create mode 100644 svgs/look4sat.svg
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index 3059e6e48d2..f440cf61c45 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -2348,6 +2348,7 @@
+
@@ -2357,6 +2358,7 @@
+
@@ -5322,6 +5324,7 @@
+
diff --git a/svgs/cuberite.svg b/svgs/cuberite.svg
new file mode 100644
index 00000000000..eb91ad479df
--- /dev/null
+++ b/svgs/cuberite.svg
@@ -0,0 +1,3 @@
+
diff --git a/svgs/custom_uploader.svg b/svgs/custom_uploader.svg
new file mode 100644
index 00000000000..885def8995c
--- /dev/null
+++ b/svgs/custom_uploader.svg
@@ -0,0 +1,3 @@
+
diff --git a/svgs/look4sat.svg b/svgs/look4sat.svg
new file mode 100644
index 00000000000..5942dcf582e
--- /dev/null
+++ b/svgs/look4sat.svg
@@ -0,0 +1,3 @@
+
From 35581a1ee6426b9920af50f1fedabae810f88545 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 29 Aug 2024 09:18:55 +0800
Subject: [PATCH 083/144] Update dependency
org.jetbrains.kotlinx:kotlinx-serialization-json to v1.7.2 (#2287)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
app/build.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index cf9f33d9ef0..934e4849cf6 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -147,7 +147,7 @@ dependencies {
implementation("androidx.navigation:navigation-compose:2.8.0-rc01")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4")
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1")
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.2")
implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7")
val hiltVersion = "2.52"
From 7a95b69165b66e29e2d41d790c32043daf22d1d2 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 30 Aug 2024 09:45:23 +0800
Subject: [PATCH 084/144] Update AGP (#2288)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
build.gradle.kts | 2 +-
svg-processor/build.gradle.kts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/build.gradle.kts b/build.gradle.kts
index fa51ad45f0a..74f2bec6281 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -2,7 +2,7 @@ import com.diffplug.gradle.spotless.SpotlessExtension
import com.diffplug.spotless.extra.wtp.EclipseWtpFormatterStep
plugins {
- id("com.android.application") version "8.5.2" apply false
+ id("com.android.application") version "8.6.0" apply false
id("org.jetbrains.kotlin.android") version "2.0.20" apply false
id("org.jetbrains.kotlin.plugin.compose") version "2.0.20"
id("org.jetbrains.kotlin.plugin.serialization") version "2.0.20" apply false
diff --git a/svg-processor/build.gradle.kts b/svg-processor/build.gradle.kts
index 2df983d5b96..83eaaf8b79a 100644
--- a/svg-processor/build.gradle.kts
+++ b/svg-processor/build.gradle.kts
@@ -8,7 +8,7 @@ application {
}
dependencies {
- implementation("com.android.tools:sdk-common:31.5.2")
+ implementation("com.android.tools:sdk-common:31.6.0")
implementation("org.dom4j:dom4j:2.1.4")
implementation("commons-io:commons-io:2.16.1")
}
From 758d919a322e9ffcebf00b82c66fe317b76eaedf Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 30 Aug 2024 19:31:40 +0800
Subject: [PATCH 085/144] Update dependency io.nlopez.compose.rules:ktlint to
v0.4.11 (#2289)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
build.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle.kts b/build.gradle.kts
index 74f2bec6281..5bb8a8f1fd1 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -31,7 +31,7 @@ allprojects {
target("src/**/*.kt")
ktlint().customRuleSets(
listOf(
- "io.nlopez.compose.rules:ktlint:0.4.10",
+ "io.nlopez.compose.rules:ktlint:0.4.11",
),
).editorConfigOverride(
mapOf(
From 81f2c9b6848077b84c25cb694508abbd917ec0da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=B5=81=E5=85=89?=
<45266046+DreamVoid@users.noreply.github.com>
Date: Sat, 31 Aug 2024 23:59:35 +0800
Subject: [PATCH 086/144] Link Raileay 12306 (#2290)
---
app/assets/appfilter.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index f440cf61c45..aea60f676fd 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -12415,6 +12415,7 @@
+
From 5ae99dba3fd1c5914d475d806907712be3b8f85e Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Sat, 31 Aug 2024 19:20:39 +0300
Subject: [PATCH 087/144] +37 links (#2291)
---
app/assets/appfilter.xml | 39 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index aea60f676fd..9e783d289bd 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -512,6 +512,7 @@
+
@@ -681,6 +682,7 @@
+
@@ -796,6 +798,7 @@
+
@@ -956,6 +959,7 @@
+
@@ -988,9 +992,11 @@
+
+
@@ -1115,6 +1121,7 @@
+
@@ -1330,6 +1337,7 @@
+
@@ -2620,6 +2628,7 @@
+
@@ -4003,6 +4012,7 @@
+
@@ -4278,6 +4288,8 @@
+
+
@@ -4361,6 +4373,7 @@
+
@@ -4395,6 +4408,7 @@
+
@@ -4830,6 +4844,7 @@
+
@@ -5116,11 +5131,11 @@
-
+
@@ -5138,6 +5153,8 @@
+
+
@@ -5537,6 +5554,7 @@
+
@@ -5804,6 +5822,8 @@
+
+
@@ -5902,6 +5922,7 @@
+
@@ -6113,6 +6134,7 @@
+
@@ -6267,6 +6289,8 @@
+
+
@@ -8245,6 +8269,7 @@
+
@@ -8887,6 +8912,7 @@
+
@@ -9489,6 +9515,7 @@
+
@@ -9685,6 +9712,7 @@
+
@@ -9816,6 +9844,7 @@
+
@@ -10108,6 +10137,7 @@
+
@@ -11076,6 +11106,7 @@
+
@@ -11363,6 +11394,7 @@
+
@@ -11371,6 +11403,7 @@
+
@@ -11759,6 +11792,7 @@
+
@@ -12024,6 +12058,7 @@
+
@@ -12265,6 +12300,7 @@
+
@@ -12329,6 +12365,7 @@
+
From d8376706c8b16e3f8cab8b384fa79d91b9025a3e Mon Sep 17 00:00:00 2001
From: Chang Jiaman
Date: Sun, 1 Sep 2024 14:43:44 +0800
Subject: [PATCH 088/144] +1 icon (#2292)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* link hihonor music, legado(play)
* add todesk,yunrili
* +6,link 1
* +2 icons
* link1
* fix icons,+1 icon
* fix
* Fixed IQIYI → iQIYI
* Improved iqiyi.svg quality for small sizes
* The visual center of ithome.svg has been clarified
* Moved kaadas.svg so that it is located within the boundaries of the content area and reduced the density at the bottom
* +1 icon
* Rename hkbank.svg to hankou_bank.svg
* Unnecessary additions have been removed
---------
Co-authored-by: Gleb <60105060+x9136@users.noreply.github.com>
---
app/assets/appfilter.xml | 1 +
svgs/hankou_bank.svg | 1 +
2 files changed, 2 insertions(+)
create mode 100644 svgs/hankou_bank.svg
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index 9e783d289bd..b5742e7a647 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -12470,6 +12470,7 @@
+
diff --git a/svgs/hankou_bank.svg b/svgs/hankou_bank.svg
new file mode 100644
index 00000000000..86e16c2a997
--- /dev/null
+++ b/svgs/hankou_bank.svg
@@ -0,0 +1 @@
+
From af69fb035ae3b6ebdb1e8a47e187b1a16b6b0995 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Wed, 4 Sep 2024 20:28:02 +0800
Subject: [PATCH 089/144] Implement build variant for play store
---
app/build.gradle.kts | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 934e4849cf6..00692471e8e 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -69,6 +69,11 @@ android {
isMinifyEnabled = true
proguardFiles("proguard-rules.pro")
}
+ create("play") {
+ applicationIdSuffix = ".play"
+ isMinifyEnabled = true
+ proguardFiles("proguard-rules.pro")
+ }
}
flavorDimensions += "product"
From 725bf6cf117b8209e977314ad71f626fa87781c8 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Wed, 4 Sep 2024 20:55:44 +0800
Subject: [PATCH 090/144] Use rememberSaveable for certain parts of the UI
Should fix some of the crashes from invalid state
---
.../lawnicons/ui/components/home/IconInfoSheet.kt | 5 +++--
.../lawnicons/ui/components/home/IconRequestFAB.kt | 7 ++++---
.../lawnicons/ui/components/home/search/SearchContents.kt | 3 ++-
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconInfoSheet.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconInfoSheet.kt
index e48e807a60d..c79a5685d7d 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconInfoSheet.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconInfoSheet.kt
@@ -29,6 +29,7 @@ import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalInspectionMode
@@ -58,7 +59,7 @@ fun IconInfoSheet(
skipPartiallyExpanded = true,
)
- val groupedComponents = remember {
+ val groupedComponents = rememberSaveable {
iconInfo.componentNames
.groupBy { it.label }
.map { (label, components) ->
@@ -71,7 +72,7 @@ fun IconInfoSheet(
newValue = "",
)
- val shareContents = remember { getShareContents(githubName, groupedComponents) }
+ val shareContents = rememberSaveable { getShareContents(githubName, groupedComponents) }
ModalBottomSheet(
onDismissRequest = {
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
index 8e3cdee83b1..20b6d652999 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
@@ -37,6 +37,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -130,13 +131,13 @@ fun RequestHandler(
val encodedRequestList = buildForm(requestList.replace("\n", "%20"))
val directLinkEnabled = encodedRequestList.length < Constants.DIRECT_LINK_MAX_LENGTH
- var sheetExpanded by remember { mutableStateOf(false) }
+ var sheetExpanded by rememberSaveable { mutableStateOf(false) }
val sheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true,
)
val scope = rememberCoroutineScope()
- val interactionSource = remember { MutableInteractionSource() }
+ val interactionSource = rememberSaveable { MutableInteractionSource() }
HandleTouchInteractions(
interactionSource = interactionSource,
@@ -307,7 +308,7 @@ private fun openSnackbarFirstLaunchContent(
val result = snackbarHostState
.showSnackbar(
message = context.getString(R.string.snackbar_request_icons_hint),
- duration = SnackbarDuration.Long,
+ duration = SnackbarDuration.Short,
)
if (result == SnackbarResult.Dismissed) {
onActionPerformed()
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
index c2f05d47838..70e482f2fae 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
@@ -30,6 +30,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -180,7 +181,7 @@ private fun IconInfoListItem(iconInfo: ImmutableList) {
return@IconInfoListItem
}
- val isIconInfoAppfilterShown = remember { mutableStateOf(false) }
+ val isIconInfoAppfilterShown = rememberSaveable { mutableStateOf(false) }
ListItem(
headlineContent = { Text(it.getFirstLabelAndComponent().label) },
From b9281485081029ac4c2f792282b12378558e5cd9 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Wed, 4 Sep 2024 22:56:30 +0800
Subject: [PATCH 091/144] Simplify code
---
.../ui/components/home/HomeTopBar.kt | 28 +++-----
.../ui/components/home/IconRequestFAB.kt | 2 +-
.../ui/components/home/OverflowMenu.kt | 58 ---------------
.../ui/components/home/search/SearchBar.kt | 70 ++++++++-----------
.../components/home/search/SearchContents.kt | 1 -
5 files changed, 39 insertions(+), 120 deletions(-)
delete mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/OverflowMenu.kt
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeTopBar.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeTopBar.kt
index cd1c1021216..9c2b6afae38 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeTopBar.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeTopBar.kt
@@ -41,10 +41,8 @@ fun HomeTopBar(
) {
val (isSearchExpanded, isExpandedScreen, searchTerm, searchMode, searchedIconInfoModel, isIconPicker) = uiState
- val condition = isSearchExpanded || isExpandedScreen
-
val offset = animateDpAsState(
- targetValue = if (condition) {
+ targetValue = if (isSearchExpanded || isExpandedScreen) {
0.dp
} else {
(-100).dp
@@ -59,7 +57,7 @@ fun HomeTopBar(
},
searchTerm = searchTerm,
onClearSearch = onClearSearch,
- onChangeMode = onChangeMode,
+ onModeChange = onChangeMode,
onSearch = onSearchIcons,
iconInfoModel = it,
onNavigate = onNavigate,
@@ -79,7 +77,7 @@ private fun SearchBar(
searchTerm: String,
onSearch: (String) -> Unit,
onClearSearch: () -> Unit,
- onChangeMode: (SearchMode) -> Unit,
+ onModeChange: (SearchMode) -> Unit,
onNavigate: () -> Unit,
isExpandedScreen: Boolean,
isIconPicker: Boolean,
@@ -97,15 +95,9 @@ private fun SearchBar(
LawniconsSearchBar(
query = searchTerm,
isQueryEmpty = searchTerm == "",
- onClear = {
- onClearSearch()
- },
- onBack = {
- onFocusChange()
- },
- onQueryChange = { newValue ->
- onSearch(newValue)
- },
+ onClear = onClearSearch,
+ onBack = onFocusChange,
+ onQueryChange = onSearch,
iconInfoModel = iconInfoModel,
onNavigate = onNavigate,
isExpandedScreen = isExpandedScreen,
@@ -114,13 +106,9 @@ private fun SearchBar(
SearchContents(
searchTerm = searchTerm,
searchMode = searchMode,
- onModeChange = { mode ->
- onChangeMode(mode)
- },
+ onModeChange = onModeChange,
iconInfo = iconInfoModel.iconInfo,
- onSendResult = {
- onSendResult(it)
- },
+ onSendResult = onSendResult,
)
},
inputFieldModifier = inputFieldModifier,
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
index 20b6d652999..2106ec0cd94 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
@@ -137,7 +137,7 @@ fun RequestHandler(
)
val scope = rememberCoroutineScope()
- val interactionSource = rememberSaveable { MutableInteractionSource() }
+ val interactionSource = remember { MutableInteractionSource() }
HandleTouchInteractions(
interactionSource = interactionSource,
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/OverflowMenu.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/OverflowMenu.kt
deleted file mode 100644
index 99caf61734b..00000000000
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/OverflowMenu.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-package app.lawnchair.lawnicons.ui.components.home
-
-import androidx.compose.foundation.layout.Box
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.rounded.MoreVert
-import androidx.compose.material3.DropdownMenu
-import androidx.compose.material3.LocalContentColor
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.DpOffset
-import androidx.compose.ui.unit.dp
-
-@Composable
-fun OverflowMenu(
- modifier: Modifier = Modifier,
- block: @Composable OverflowMenuScope.() -> Unit,
-) {
- val showMenu = remember { mutableStateOf(false) }
- val overflowMenuScope = remember { OverflowMenuScopeImpl(showMenu) }
-
- Box(
- modifier = modifier,
- ) {
- ClickableIcon(
- imageVector = Icons.Rounded.MoreVert,
- size = 52.dp,
- onClick = { showMenu.value = true },
- )
- DropdownMenu(
- expanded = showMenu.value,
- onDismissRequest = { showMenu.value = false },
- offset = DpOffset(x = 16.dp, y = (-36).dp),
- ) {
- CompositionLocalProvider(
- LocalContentColor
- provides MaterialTheme.colorScheme.onSurface,
- ) {
- block(overflowMenuScope)
- }
- }
- }
-}
-
-interface OverflowMenuScope {
- fun hideMenu()
-}
-
-private class OverflowMenuScopeImpl(private val showState: MutableState) :
- OverflowMenuScope {
- override fun hideMenu() {
- showState.value = false
- }
-}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchBar.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchBar.kt
index 435cd245b92..c2e1d4ac3d5 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchBar.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchBar.kt
@@ -5,6 +5,7 @@ import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
@@ -214,8 +215,23 @@ private fun ResponsiveSearchBar(
isExpandedScreen: Boolean,
modifier: Modifier = Modifier,
inputFieldModifier: Modifier = Modifier,
- content: @Composable () -> Unit,
+ content: @Composable ColumnScope.() -> Unit,
) {
+ val inputField =
+ @Composable {
+ SearchBarDefaults.InputField(
+ query = query,
+ onQueryChange = onQueryChange,
+ onSearch = onSearch,
+ modifier = inputFieldModifier,
+ expanded = active,
+ onExpandedChange = onActiveChange,
+ placeholder = placeholder,
+ leadingIcon = leadingIcon,
+ trailingIcon = trailingIcon,
+ )
+ }
+
if (isExpandedScreen) {
Row(
verticalAlignment = Alignment.CenterVertically,
@@ -223,47 +239,19 @@ private fun ResponsiveSearchBar(
modifier = modifier,
) {
DockedSearchBar(
- inputField = {
- SearchBarDefaults.InputField(
- query = query,
- onQueryChange = onQueryChange,
- onSearch = onSearch,
- modifier = inputFieldModifier,
- expanded = active,
- onExpandedChange = onActiveChange,
- placeholder = placeholder,
- leadingIcon = leadingIcon,
- trailingIcon = trailingIcon,
- )
- },
+ inputField = inputField,
expanded = active,
onExpandedChange = onActiveChange,
- content = {
- content()
- },
+ content = content,
)
}
} else {
SearchBar(
- inputField = {
- SearchBarDefaults.InputField(
- query = query,
- onQueryChange = onQueryChange,
- onSearch = onSearch,
- modifier = inputFieldModifier,
- expanded = active,
- onExpandedChange = onActiveChange,
- placeholder = placeholder,
- leadingIcon = leadingIcon,
- trailingIcon = trailingIcon,
- )
- },
+ inputField = inputField,
expanded = active,
onExpandedChange = onActiveChange,
modifier = Modifier.fillMaxWidth(),
- content = {
- content()
- },
+ content = content,
)
}
}
@@ -273,13 +261,15 @@ internal fun SearchIcon(
active: Boolean,
onButtonClick: () -> Unit,
) {
- if (active) {
- ClickableIcon(
- imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
- onClick = onButtonClick,
- )
- } else {
- Icon(Icons.Rounded.Search, contentDescription = null)
+ Crossfade(active, label = "") {
+ if (it) {
+ ClickableIcon(
+ imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
+ onClick = onButtonClick,
+ )
+ } else {
+ Icon(Icons.Rounded.Search, contentDescription = null)
+ }
}
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
index 70e482f2fae..bd919f75d08 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
@@ -29,7 +29,6 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
From 1292415090e193e6c1dbda37db5d684815234dbd Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Thu, 5 Sep 2024 00:10:42 +0800
Subject: [PATCH 092/144] Add background to scrollbar, highlight icons on
scrollbar click
When selecting the scrollbar, the icons with the same letter will now be scaled (110%) to highlight that they are the same category.
Further improvements can be made after discussion.
---
.../ui/components/home/IconPreview.kt | 13 +--
.../ui/components/home/IconPreviewGrid.kt | 102 ++++++++++++------
2 files changed, 79 insertions(+), 36 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreview.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreview.kt
index 213ae98691b..8847e7801de 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreview.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreview.kt
@@ -33,11 +33,12 @@ import app.lawnchair.lawnicons.ui.util.PreviewLawnicons
import app.lawnchair.lawnicons.ui.util.SampleData
import kotlin.math.ln
-private fun ColorScheme.iconColor(): Color {
- val elevation = 3.dp
- val alpha = ((4.5f * ln(elevation.value + 1)) + 2f) / 100f
- return primary.copy(alpha = alpha).compositeOver(surface)
-}
+val ColorScheme.iconColor: Color
+ get() {
+ val elevation = 3.dp
+ val alpha = ((4.5f * ln(elevation.value + 1)) + 2f) / 100f
+ return primary.copy(alpha = alpha).compositeOver(surface)
+ }
@Composable
fun IconPreview(
@@ -68,7 +69,7 @@ fun IconPreview(
color = iconBackground ?: if (isIconInfoShown.value) {
MaterialTheme.colorScheme.surfaceVariant
} else {
- MaterialTheme.colorScheme.iconColor()
+ MaterialTheme.colorScheme.iconColor
},
),
) {
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
index 92c81d274b2..8dd5edfc33e 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
@@ -1,6 +1,7 @@
package app.lawnchair.lawnicons.ui.components.home
import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ExperimentalFoundationApi
@@ -9,13 +10,14 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars
+import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
@@ -27,15 +29,21 @@ import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
+import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
@@ -48,7 +56,7 @@ import app.lawnchair.lawnicons.ui.util.SampleData
import app.lawnchair.lawnicons.ui.util.toPaddingValues
import app.lawnchair.lawnicons.util.appIcon
import kotlinx.collections.immutable.ImmutableList
-import my.nanihadesuka.compose.LazyVerticalGridScrollbar
+import my.nanihadesuka.compose.InternalLazyVerticalGridScrollbar
import my.nanihadesuka.compose.ScrollbarSelectionMode
import my.nanihadesuka.compose.ScrollbarSettings
@@ -63,34 +71,31 @@ fun IconPreviewGrid(
contentPadding: PaddingValues? = null,
gridState: LazyGridState = rememberLazyGridState(),
) {
- val indexOfFirstItem = remember { derivedStateOf { gridState.firstVisibleItemIndex } }
- val letter = iconInfo[indexOfFirstItem.value].label[0].uppercase()
+ val indexOfFirstItem by remember { derivedStateOf { gridState.firstVisibleItemIndex } }
+ val letter = iconInfo[indexOfFirstItem].label[0].uppercase()
+ var thumbSelected by remember { mutableStateOf(false) }
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = modifier.fillMaxWidth(),
) {
- LazyVerticalGridScrollbar(
+ val horizontalGridPadding = if (isExpandedScreen) 32.dp else 8.dp
+ Box(
modifier = Modifier
.widthIn(max = 640.dp)
.fillMaxWidth()
.statusBarsPadding()
.then(
- if (isExpandedScreen) Modifier.padding(top = 26.dp) else Modifier.padding(bottom = 80.dp),
+ if (isExpandedScreen) {
+ Modifier.padding(top = 26.dp)
+ } else {
+ Modifier.padding(
+ bottom = 80.dp,
+ )
+ },
),
- state = gridState,
- settings = ScrollbarSettings(
- alwaysShowScrollbar = true,
- thumbUnselectedColor = MaterialTheme.colorScheme.primaryContainer,
- thumbSelectedColor = MaterialTheme.colorScheme.primary,
- selectionMode = ScrollbarSelectionMode.Thumb,
- ),
- indicatorContent = { _, isThumbSelected ->
- ScrollbarIndicator(letter, isThumbSelected)
- },
) {
- val horizontalGridPadding = if (isExpandedScreen) 32.dp else 8.dp
LazyVerticalGrid(
columns = GridCells.Adaptive(minSize = 80.dp),
contentPadding = contentPadding ?: WindowInsets.navigationBars.toPaddingValues(
@@ -106,26 +111,63 @@ fun IconPreviewGrid(
GridItemSpan(maxLineSpan)
},
) {
- TopAppBar()
+ AppBarListItem()
+ }
+ items(
+ items = iconInfo,
+ contentType = { "icon_preview" },
+ ) { iconInfo ->
+ val scale by animateFloatAsState(
+ if (thumbSelected && iconInfo.label.first()
+ .toString() == letter
+ ) {
+ 1.1f
+ } else {
+ 1f
+ },
+ label = "",
+ )
+ IconPreview(
+ modifier = Modifier
+ .scale(scale),
+ iconInfo = iconInfo,
+ isIconPicker = isIconPicker,
+ onSendResult = onSendResult,
+ )
}
}
- items(
- items = iconInfo,
- contentType = { "icon_preview" },
- ) { iconInfo ->
- IconPreview(
- iconInfo = iconInfo,
- isIconPicker = isIconPicker,
- onSendResult = onSendResult,
- )
- }
+ }
+ Box(
+ contentAlignment = Alignment.CenterEnd,
+ ) {
+ Spacer(
+ Modifier
+ .fillMaxHeight()
+ .width(8.dp)
+ .background(MaterialTheme.colorScheme.surfaceContainer)
+ .clip(CircleShape),
+ )
+ InternalLazyVerticalGridScrollbar(
+ modifier = Modifier.offset(7.dp),
+ state = gridState,
+ settings = ScrollbarSettings(
+ alwaysShowScrollbar = true,
+ thumbUnselectedColor = MaterialTheme.colorScheme.primary,
+ thumbSelectedColor = MaterialTheme.colorScheme.primary,
+ selectionMode = ScrollbarSelectionMode.Thumb,
+ ),
+ indicatorContent = { _, isThumbSelected ->
+ thumbSelected = isThumbSelected
+ ScrollbarIndicator(letter, isThumbSelected)
+ },
+ )
}
}
}
}
@Composable
-private fun ColumnScope.ScrollbarIndicator(
+private fun ScrollbarIndicator(
label: String,
isThumbSelected: Boolean,
) {
@@ -154,7 +196,7 @@ private fun ColumnScope.ScrollbarIndicator(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
-fun TopAppBar(modifier: Modifier = Modifier) {
+private fun AppBarListItem(modifier: Modifier = Modifier) {
val context = LocalContext.current
CenterAlignedTopAppBar(
modifier = modifier,
From 65462534f7fd1a3a251dfabcbc8ec82e50be33f3 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 5 Sep 2024 09:10:16 +0800
Subject: [PATCH 093/144] Update dependency
androidx.compose.material3:material3 to v1.3.0 (#2301)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
app/build.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 00692471e8e..aa7b138b548 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -147,7 +147,7 @@ dependencies {
debugImplementation("androidx.compose.ui:ui-tooling")
implementation("androidx.compose.animation:animation")
implementation("androidx.compose.material:material-icons-core-android:1.6.8")
- implementation("androidx.compose.material3:material3:1.3.0-rc01")
+ implementation("androidx.compose.material3:material3:1.3.0")
implementation("androidx.compose.material3:material3-window-size-class")
implementation("androidx.navigation:navigation-compose:2.8.0-rc01")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4")
From b74ea4dc965fab0cfb77ac680c289423132a87f2 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 5 Sep 2024 09:10:27 +0800
Subject: [PATCH 094/144] Update dependency androidx.activity:activity-compose
to v1.9.2 (#2300)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
app/build.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index aa7b138b548..593c59e1b60 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -139,7 +139,7 @@ licensee {
dependencies {
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.core:core-splashscreen:1.0.1")
- implementation("androidx.activity:activity-compose:1.9.1")
+ implementation("androidx.activity:activity-compose:1.9.2")
implementation(platform("androidx.compose:compose-bom:2024.08.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-tooling-preview")
From adbc56b285913960d74993bea5c2704d482a0b9d Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 5 Sep 2024 09:19:05 +0800
Subject: [PATCH 095/144] Update dependency
androidx.navigation:navigation-compose to v2.8.0 (#2303)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
app/build.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 593c59e1b60..031ab6089dc 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -149,7 +149,7 @@ dependencies {
implementation("androidx.compose.material:material-icons-core-android:1.6.8")
implementation("androidx.compose.material3:material3:1.3.0")
implementation("androidx.compose.material3:material3-window-size-class")
- implementation("androidx.navigation:navigation-compose:2.8.0-rc01")
+ implementation("androidx.navigation:navigation-compose:2.8.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.2")
From 0db2a48bb7dba4ee9dca638a97d0180eb4976ee1 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 5 Sep 2024 09:19:58 +0800
Subject: [PATCH 096/144] Update dependency
androidx.lifecycle:lifecycle-viewmodel-compose to v2.8.5 (#2302)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
app/build.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 031ab6089dc..3d622851d5b 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -150,7 +150,7 @@ dependencies {
implementation("androidx.compose.material3:material3:1.3.0")
implementation("androidx.compose.material3:material3-window-size-class")
implementation("androidx.navigation:navigation-compose:2.8.0")
- implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4")
+ implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.5")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.2")
implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7")
From 00fe17ce7f175180b46e6d14df1307f8d89f29cf Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 5 Sep 2024 09:26:45 +0800
Subject: [PATCH 097/144] Update dependency
androidx.compose.material:material-icons-core-android to v1.7.0 (#2304)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
app/build.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 3d622851d5b..9fd5328e8e4 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -146,7 +146,7 @@ dependencies {
implementation("androidx.compose.ui:ui-util")
debugImplementation("androidx.compose.ui:ui-tooling")
implementation("androidx.compose.animation:animation")
- implementation("androidx.compose.material:material-icons-core-android:1.6.8")
+ implementation("androidx.compose.material:material-icons-core-android:1.7.0")
implementation("androidx.compose.material3:material3:1.3.0")
implementation("androidx.compose.material3:material3-window-size-class")
implementation("androidx.navigation:navigation-compose:2.8.0")
From bf13365326c7fc6f4e375842e90a470c142a1277 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 5 Sep 2024 09:27:57 +0800
Subject: [PATCH 098/144] Update dependency androidx.compose:compose-bom to
v2024.09.00 (#2305)
* Update dependency androidx.compose:compose-bom to v2024.09.00
* Tweaks
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Goooler
---
app/build.gradle.kts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 9fd5328e8e4..e720ad5decd 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -140,14 +140,14 @@ dependencies {
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.activity:activity-compose:1.9.2")
- implementation(platform("androidx.compose:compose-bom:2024.08.00"))
+ implementation(platform("androidx.compose:compose-bom:2024.09.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.ui:ui-util")
debugImplementation("androidx.compose.ui:ui-tooling")
implementation("androidx.compose.animation:animation")
- implementation("androidx.compose.material:material-icons-core-android:1.7.0")
- implementation("androidx.compose.material3:material3:1.3.0")
+ implementation("androidx.compose.material:material-icons-core-android")
+ implementation("androidx.compose.material3:material3")
implementation("androidx.compose.material3:material3-window-size-class")
implementation("androidx.navigation:navigation-compose:2.8.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.5")
From 569ab75b984265fde71dbd0ad18b87fa4a47a54e Mon Sep 17 00:00:00 2001
From: "M."
Date: Thu, 5 Sep 2024 11:11:02 +0330
Subject: [PATCH 099/144] +1 icon (#2294)
* added Beanconqueror
* updated svg
* Fix
* Minor fix
---------
Co-authored-by: Gleb <60105060+x9136@users.noreply.github.com>
---
app/assets/appfilter.xml | 3 ++-
svgs/beanconqueror.svg | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
create mode 100644 svgs/beanconqueror.svg
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index b5742e7a647..7d396578232 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -954,6 +954,7 @@
+
@@ -12377,6 +12378,7 @@
+
@@ -12470,7 +12472,6 @@
-
diff --git a/svgs/beanconqueror.svg b/svgs/beanconqueror.svg
new file mode 100644
index 00000000000..8a743ef6a8c
--- /dev/null
+++ b/svgs/beanconqueror.svg
@@ -0,0 +1 @@
+
From 33db100912bbf4b77c218442bf5159ba12dd07d7 Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Thu, 5 Sep 2024 11:06:32 +0300
Subject: [PATCH 100/144] Lawnicons update, +14 links (#2306)
---
app/assets/appfilter.xml | 52 ++++++++++++-------
svgs/{gta_sa.svg => gta_san_andreas.svg} | 0
svgs/{gta_vc.svg => gta_vice_city.svg} | 0
svgs/lawnicons.svg | 2 +-
...off_invest.svg => tinkoff_investments.svg} | 0
...craft.svg => toolbox_for_minecraft_pe.svg} | 0
6 files changed, 34 insertions(+), 20 deletions(-)
rename svgs/{gta_sa.svg => gta_san_andreas.svg} (100%)
rename svgs/{gta_vc.svg => gta_vice_city.svg} (100%)
rename svgs/{tinkoff_invest.svg => tinkoff_investments.svg} (100%)
rename svgs/{toolbox_for_minecraft.svg => toolbox_for_minecraft_pe.svg} (100%)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index 7d396578232..d58db01649e 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -319,6 +319,7 @@
+
@@ -389,6 +390,7 @@
+
@@ -4079,6 +4081,7 @@
+
@@ -4155,21 +4158,22 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4814,6 +4818,7 @@
+
@@ -5121,6 +5126,7 @@
+
@@ -7219,6 +7225,7 @@
+
@@ -7534,6 +7541,7 @@
+
@@ -10646,8 +10654,9 @@
-
-
+
+
+
@@ -10662,6 +10671,7 @@
+
@@ -11793,6 +11803,8 @@
+
+
@@ -11893,6 +11905,7 @@
+
@@ -12171,8 +12184,9 @@
-
-
+
+
+
diff --git a/svgs/gta_sa.svg b/svgs/gta_san_andreas.svg
similarity index 100%
rename from svgs/gta_sa.svg
rename to svgs/gta_san_andreas.svg
diff --git a/svgs/gta_vc.svg b/svgs/gta_vice_city.svg
similarity index 100%
rename from svgs/gta_vc.svg
rename to svgs/gta_vice_city.svg
diff --git a/svgs/lawnicons.svg b/svgs/lawnicons.svg
index 7f48dd1e280..1a5943746ba 100644
--- a/svgs/lawnicons.svg
+++ b/svgs/lawnicons.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/tinkoff_invest.svg b/svgs/tinkoff_investments.svg
similarity index 100%
rename from svgs/tinkoff_invest.svg
rename to svgs/tinkoff_investments.svg
diff --git a/svgs/toolbox_for_minecraft.svg b/svgs/toolbox_for_minecraft_pe.svg
similarity index 100%
rename from svgs/toolbox_for_minecraft.svg
rename to svgs/toolbox_for_minecraft_pe.svg
From 43080ffd28417853354a9435f99c22d044314cee Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Thu, 5 Sep 2024 17:18:26 +0800
Subject: [PATCH 101/144] Fix grid not showing on expanded devices
---
.../ui/components/home/IconPreviewGrid.kt | 91 ++++++++++++-------
1 file changed, 57 insertions(+), 34 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
index 8dd5edfc33e..98284cb58a6 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
@@ -33,6 +33,7 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
@@ -46,6 +47,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import app.lawnchair.lawnicons.R
@@ -113,28 +115,28 @@ fun IconPreviewGrid(
) {
AppBarListItem()
}
- items(
- items = iconInfo,
- contentType = { "icon_preview" },
- ) { iconInfo ->
- val scale by animateFloatAsState(
- if (thumbSelected && iconInfo.label.first()
- .toString() == letter
- ) {
- 1.1f
- } else {
- 1f
- },
- label = "",
- )
- IconPreview(
- modifier = Modifier
- .scale(scale),
- iconInfo = iconInfo,
- isIconPicker = isIconPicker,
- onSendResult = onSendResult,
- )
- }
+ }
+ items(
+ items = iconInfo,
+ contentType = { "icon_preview" },
+ ) { iconInfo ->
+ val scale by animateFloatAsState(
+ if (thumbSelected && iconInfo.label.first()
+ .toString() == letter
+ ) {
+ 1.1f
+ } else {
+ 1f
+ },
+ label = "",
+ )
+ IconPreview(
+ modifier = Modifier
+ .scale(scale),
+ iconInfo = iconInfo,
+ isIconPicker = isIconPicker,
+ onSendResult = onSendResult,
+ )
}
}
Box(
@@ -204,11 +206,13 @@ private fun AppBarListItem(modifier: Modifier = Modifier) {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
- Image(
- bitmap = context.appIcon().asImageBitmap(),
- contentDescription = stringResource(id = R.string.app_name),
- modifier = Modifier.size(36.dp),
- )
+ if (!LocalInspectionMode.current) {
+ Image(
+ bitmap = context.appIcon().asImageBitmap(),
+ contentDescription = stringResource(id = R.string.app_name),
+ modifier = Modifier.size(36.dp),
+ )
+ }
Spacer(modifier = Modifier.width(8.dp))
Text(
stringResource(id = R.string.app_name),
@@ -223,12 +227,31 @@ private fun AppBarListItem(modifier: Modifier = Modifier) {
@Composable
private fun IconGridPreview() {
LawniconsTheme {
- IconPreviewGrid(
- SampleData.iconInfoList,
- true,
- {},
- Modifier,
- false,
- )
+ Surface {
+ IconPreviewGrid(
+ iconInfo = SampleData.iconInfoList,
+ isExpandedScreen = false,
+ onSendResult = {},
+ modifier = Modifier,
+ isIconPicker = false,
+ )
+ }
+ }
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+@PreviewLawnicons
+@Composable
+private fun IconGridExpandedPreview() {
+ LawniconsTheme {
+ Surface {
+ IconPreviewGrid(
+ iconInfo = SampleData.iconInfoList,
+ isExpandedScreen = true,
+ onSendResult = {},
+ modifier = Modifier,
+ isIconPicker = false,
+ )
+ }
}
}
From 9ec06e57e745cf4bd8fa5ec9cd663eb5163ec883 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Thu, 5 Sep 2024 17:27:57 +0800
Subject: [PATCH 102/144] Rename `onChange` to `toggle`
---
.../app/lawnchair/lawnicons/repository/PreferenceManager.kt | 5 ++++-
.../lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
index 9a9e7a2a448..b641936f866 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
@@ -28,7 +28,7 @@ abstract class BasePreferenceManager(
fun get() = prefs.getBoolean(key, defaultValue)
fun set(value: Boolean) = editor.putBoolean(key, value).apply()
- fun onChange() = set(!get())
+ fun toggle() = set(!get())
@Composable
fun asState(): State {
@@ -39,6 +39,9 @@ abstract class BasePreferenceManager(
}
}
prefs.registerOnSharedPreferenceChangeListener(listener)
+ awaitDispose {
+ prefs.unregisterOnSharedPreferenceChangeListener(listener)
+ }
}
}
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
index 2106ec0cd94..53dfd79868d 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
@@ -159,7 +159,7 @@ fun RequestHandler(
openSnackbarFirstLaunchContent(
context,
scope,
- prefs.showFirstLaunchSnackbar::onChange,
+ prefs.showFirstLaunchSnackbar::toggle,
snackbarHostState,
)
}
From 5155f127830fa02bbbb8dbe9a09472fb64c6ab5a Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 6 Sep 2024 08:23:44 +0800
Subject: [PATCH 103/144] Update Kotlin and KSP (#2307)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
app/build.gradle.kts | 2 +-
build.gradle.kts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index e720ad5decd..1fb5382ed6d 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -153,7 +153,7 @@ dependencies {
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.5")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.2")
- implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7")
+ implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.8")
val hiltVersion = "2.52"
implementation("com.google.dagger:hilt-android:$hiltVersion")
diff --git a/build.gradle.kts b/build.gradle.kts
index 5bb8a8f1fd1..85c2d418d08 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -6,7 +6,7 @@ plugins {
id("org.jetbrains.kotlin.android") version "2.0.20" apply false
id("org.jetbrains.kotlin.plugin.compose") version "2.0.20"
id("org.jetbrains.kotlin.plugin.serialization") version "2.0.20" apply false
- id("com.google.devtools.ksp") version "2.0.20-1.0.24" apply false
+ id("com.google.devtools.ksp") version "2.0.20-1.0.25" apply false
id("com.google.dagger.hilt.android") version "2.52" apply false
id("app.cash.licensee") version "1.11.0" apply false
id("com.diffplug.spotless") version "6.25.0" apply false
From f401a40db060eb759f96e2b03030158abc319973 Mon Sep 17 00:00:00 2001
From: Zongle Wang
Date: Fri, 6 Sep 2024 06:16:04 -0400
Subject: [PATCH 104/144] Rearrange nav destinations (#2284)
---
.../app/lawnchair/lawnicons/ui/Lawnicons.kt | 79 ++++-----
.../lawnicons/ui/destination/About.kt | 166 ++++++++++--------
.../ui/destination/Acknowledgement.kt | 26 ++-
.../ui/destination/Acknowledgements.kt | 22 ++-
.../lawnicons/ui/destination/Contributors.kt | 25 ++-
.../lawnicons/ui/destination/Home.kt | 24 ++-
.../lawnicons/ui/util/Destinations.kt | 18 --
7 files changed, 217 insertions(+), 143 deletions(-)
delete mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/Destinations.kt
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt
index 5fa7cc626f1..5562654a521 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt
@@ -9,20 +9,18 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.LayoutDirection
import androidx.navigation.compose.NavHost
-import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
-import androidx.navigation.toRoute
import app.lawnchair.lawnicons.model.IconInfo
import app.lawnchair.lawnicons.ui.destination.About
import app.lawnchair.lawnicons.ui.destination.Acknowledgement
import app.lawnchair.lawnicons.ui.destination.Acknowledgements
import app.lawnchair.lawnicons.ui.destination.Contributors
import app.lawnchair.lawnicons.ui.destination.Home
-import app.lawnchair.lawnicons.ui.util.About
-import app.lawnchair.lawnicons.ui.util.Acknowledgement
-import app.lawnchair.lawnicons.ui.util.Acknowledgements
-import app.lawnchair.lawnicons.ui.util.Contributors
-import app.lawnchair.lawnicons.ui.util.Home
+import app.lawnchair.lawnicons.ui.destination.aboutDestination
+import app.lawnchair.lawnicons.ui.destination.acknowledgementDestination
+import app.lawnchair.lawnicons.ui.destination.acknowledgementsDestination
+import app.lawnchair.lawnicons.ui.destination.contributorsDestination
+import app.lawnchair.lawnicons.ui.destination.homeDestination
import soup.compose.material.motion.animation.materialSharedAxisXIn
import soup.compose.material.motion.animation.materialSharedAxisXOut
import soup.compose.material.motion.animation.rememberSlideDistance
@@ -50,42 +48,37 @@ fun Lawnicons(
popEnterTransition = { materialSharedAxisXIn(isRtl, slideDistance) },
popExitTransition = { materialSharedAxisXOut(isRtl, slideDistance) },
) {
- composable {
- Home(
- onNavigate = { navController.navigate(About) },
- isExpandedScreen = isExpandedScreen,
- isIconPicker = isIconPicker,
- onSendResult = onSendResult,
- )
- }
- composable {
- Acknowledgements(
- onBack = navController::popBackStack,
- onNavigate = {
- navController.navigate(Acknowledgement(it))
- },
- isExpandedScreen = isExpandedScreen,
- )
- }
- composable { backStackEntry ->
- val acknowledgement: Acknowledgement = backStackEntry.toRoute()
- Acknowledgement(
- name = acknowledgement.id,
- onBack = navController::popBackStack,
- isExpandedScreen = isExpandedScreen,
- )
- }
- composable {
- About(
- onBack = navController::popBackStack,
- onNavigateToContributors = { navController.navigate(Contributors) },
- onNavigateToAcknowledgements = { navController.navigate(Acknowledgements) },
- isExpandedScreen = isExpandedScreen,
- )
- }
- composable {
- Contributors(onBack = navController::popBackStack, isExpandedScreen = isExpandedScreen)
- }
+ homeDestination(
+ onNavigate = { navController.navigate(About) },
+ isExpandedScreen = isExpandedScreen,
+ isIconPicker = isIconPicker,
+ onSendResult = onSendResult,
+ )
+ acknowledgementsDestination(
+ onBack = navController::popBackStack,
+ onNavigate = {
+ navController.navigate(Acknowledgement(it))
+ },
+ isExpandedScreen = isExpandedScreen,
+ )
+ acknowledgementDestination(
+ onBack = navController::popBackStack,
+ isExpandedScreen = isExpandedScreen,
+ )
+ aboutDestination(
+ onBack = navController::popBackStack,
+ onNavigateToContributors = {
+ navController.navigate(Contributors)
+ },
+ onNavigateToAcknowledgements = {
+ navController.navigate(Acknowledgements)
+ },
+ isExpandedScreen = isExpandedScreen,
+ )
+ contributorsDestination(
+ onBack = navController::popBackStack,
+ isExpandedScreen = isExpandedScreen,
+ )
}
}
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/About.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/About.kt
index 68a70354255..8f94c65b0e0 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/About.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/About.kt
@@ -25,6 +25,8 @@ import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
import app.lawnchair.lawnicons.BuildConfig
import app.lawnchair.lawnicons.R
import app.lawnchair.lawnicons.ui.components.ContributorRow
@@ -38,82 +40,29 @@ import app.lawnchair.lawnicons.ui.util.Contributor
import app.lawnchair.lawnicons.ui.util.ExternalLink
import app.lawnchair.lawnicons.ui.util.PreviewLawnicons
import app.lawnchair.lawnicons.util.appIcon
+import kotlinx.serialization.Serializable
-private val externalLinks = listOf(
- ExternalLink(
- iconResId = R.drawable.github_foreground,
- name = R.string.github,
- url = Constants.GITHUB,
- ),
- ExternalLink(
- iconResId = R.drawable.icon_request_app,
- name = R.string.request_form,
- url = Constants.ICON_REQUEST_FORM,
- ),
-)
+@Serializable
+data object About
-private val coreContributors = listOf(
- Contributor(
- name = "Suphon T.",
- username = "paphonb",
- photoUrl = "https://avatars.githubusercontent.com/u/8080853",
- socialUrl = "https://x.com/paphonb",
- descriptionRes = R.string.contribution_core,
- ),
- Contributor(
- name = "SuperDragonXD",
- username = "SuperDragonXD",
- photoUrl = "https://avatars.githubusercontent.com/u/70206496",
- socialUrl = "https://github.com/SuperDragonXD",
- descriptionRes = R.string.contribution_core,
- ),
- Contributor(
- name = "Patryk Radziszewski",
- username = "Chefski",
- photoUrl = "https://avatars.githubusercontent.com/u/100310118",
- socialUrl = "https://github.com/Chefski",
- descriptionRes = R.string.contribution_icons,
- ),
- Contributor(
- name = "Gleb",
- username = "x9136",
- photoUrl = "https://avatars.githubusercontent.com/u/60105060",
- socialUrl = "https://github.com/x9136",
- descriptionRes = R.string.contribution_icons,
- ),
- Contributor(
- name = "Grabster",
- username = "Grabstertv",
- photoUrl = "https://avatars.githubusercontent.com/u/49114212",
- socialUrl = "https://x.com/grabstertv",
- descriptionRes = R.string.contribution_icons,
- ),
- Contributor(
- name = "Zongle Wang",
- username = "Goooler",
- photoUrl = "https://avatars.githubusercontent.com/u/10363352",
- socialUrl = "https://androiddev.social/@Goooler",
- descriptionRes = R.string.contribution_infra,
- ),
-)
-
-private val specialThanks = listOf(
- Contributor(
- name = "Eatos",
- photoUrl = "https://avatars.githubusercontent.com/u/52837599",
- socialUrl = "https://x.com/eatosapps",
- descriptionRes = R.string.special_thanks_icon,
- ),
- Contributor(
- name = "Rik Koedoot",
- photoUrl = "https://avatars.githubusercontent.com/u/29402532",
- username = "rikkoedoot",
- descriptionRes = R.string.special_thanks_name,
- ),
-)
+fun NavGraphBuilder.aboutDestination(
+ onBack: () -> Unit,
+ onNavigateToContributors: () -> Unit,
+ onNavigateToAcknowledgements: () -> Unit,
+ isExpandedScreen: Boolean,
+) {
+ composable {
+ About(
+ onBack = onBack,
+ onNavigateToContributors = onNavigateToContributors,
+ onNavigateToAcknowledgements = onNavigateToAcknowledgements,
+ isExpandedScreen = isExpandedScreen,
+ )
+ }
+}
@Composable
-fun About(
+private fun About(
onBack: () -> Unit,
onNavigateToContributors: () -> Unit,
onNavigateToAcknowledgements: () -> Unit,
@@ -238,6 +187,79 @@ fun About(
}
}
+private val externalLinks = listOf(
+ ExternalLink(
+ iconResId = R.drawable.github_foreground,
+ name = R.string.github,
+ url = Constants.GITHUB,
+ ),
+ ExternalLink(
+ iconResId = R.drawable.icon_request_app,
+ name = R.string.request_form,
+ url = Constants.ICON_REQUEST_FORM,
+ ),
+)
+
+private val coreContributors = listOf(
+ Contributor(
+ name = "Suphon T.",
+ username = "paphonb",
+ photoUrl = "https://avatars.githubusercontent.com/u/8080853",
+ socialUrl = "https://x.com/paphonb",
+ descriptionRes = R.string.contribution_core,
+ ),
+ Contributor(
+ name = "SuperDragonXD",
+ username = "SuperDragonXD",
+ photoUrl = "https://avatars.githubusercontent.com/u/70206496",
+ socialUrl = "https://github.com/SuperDragonXD",
+ descriptionRes = R.string.contribution_core,
+ ),
+ Contributor(
+ name = "Patryk Radziszewski",
+ username = "Chefski",
+ photoUrl = "https://avatars.githubusercontent.com/u/100310118",
+ socialUrl = "https://github.com/Chefski",
+ descriptionRes = R.string.contribution_icons,
+ ),
+ Contributor(
+ name = "Gleb",
+ username = "x9136",
+ photoUrl = "https://avatars.githubusercontent.com/u/60105060",
+ socialUrl = "https://github.com/x9136",
+ descriptionRes = R.string.contribution_icons,
+ ),
+ Contributor(
+ name = "Grabster",
+ username = "Grabstertv",
+ photoUrl = "https://avatars.githubusercontent.com/u/49114212",
+ socialUrl = "https://x.com/grabstertv",
+ descriptionRes = R.string.contribution_icons,
+ ),
+ Contributor(
+ name = "Zongle Wang",
+ username = "Goooler",
+ photoUrl = "https://avatars.githubusercontent.com/u/10363352",
+ socialUrl = "https://androiddev.social/@Goooler",
+ descriptionRes = R.string.contribution_infra,
+ ),
+)
+
+private val specialThanks = listOf(
+ Contributor(
+ name = "Eatos",
+ photoUrl = "https://avatars.githubusercontent.com/u/52837599",
+ socialUrl = "https://x.com/eatosapps",
+ descriptionRes = R.string.special_thanks_icon,
+ ),
+ Contributor(
+ name = "Rik Koedoot",
+ photoUrl = "https://avatars.githubusercontent.com/u/29402532",
+ username = "rikkoedoot",
+ descriptionRes = R.string.special_thanks_name,
+ ),
+)
+
@PreviewLawnicons
@Composable
private fun AboutPreview() {
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Acknowledgement.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Acknowledgement.kt
index 3e3f492eab2..23347bf7207 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Acknowledgement.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Acknowledgement.kt
@@ -28,22 +28,40 @@ import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
+import androidx.navigation.toRoute
import app.lawnchair.lawnicons.ui.components.core.LawniconsScaffold
import app.lawnchair.lawnicons.ui.components.core.placeholder.PlaceholderHighlight
import app.lawnchair.lawnicons.ui.components.core.placeholder.fade
import app.lawnchair.lawnicons.ui.components.core.placeholder.placeholder
import app.lawnchair.lawnicons.viewmodel.AcknowledgementViewModel
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class Acknowledgement(val id: String)
+
+fun NavGraphBuilder.acknowledgementDestination(
+ isExpandedScreen: Boolean,
+ onBack: () -> Unit,
+) {
+ composable { backStackEntry ->
+ Acknowledgement(
+ name = backStackEntry.toRoute().id,
+ onBack = onBack,
+ isExpandedScreen = isExpandedScreen,
+ )
+ }
+}
@Composable
-fun Acknowledgement(
- name: String?,
+private fun Acknowledgement(
+ name: String,
onBack: () -> Unit,
isExpandedScreen: Boolean,
modifier: Modifier = Modifier,
acknowledgementViewModel: AcknowledgementViewModel = hiltViewModel(),
) {
- requireNotNull(name)
-
val notice by acknowledgementViewModel.getNoticeForOssLibrary(
ossLibraryName = name,
linkStyle = SpanStyle(
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Acknowledgements.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Acknowledgements.kt
index 215dade5260..7667df30df2 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Acknowledgements.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Acknowledgements.kt
@@ -14,13 +14,33 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
import app.lawnchair.lawnicons.R
import app.lawnchair.lawnicons.ui.components.core.LawniconsScaffold
import app.lawnchair.lawnicons.ui.components.core.SimpleListRow
import app.lawnchair.lawnicons.viewmodel.AcknowledgementViewModel
+import kotlinx.serialization.Serializable
+
+@Serializable
+data object Acknowledgements
+
+fun NavGraphBuilder.acknowledgementsDestination(
+ isExpandedScreen: Boolean,
+ onBack: () -> Unit,
+ onNavigate: (String) -> Unit,
+) {
+ composable {
+ Acknowledgements(
+ onBack = onBack,
+ onNavigate = onNavigate,
+ isExpandedScreen = isExpandedScreen,
+ )
+ }
+}
@Composable
-fun Acknowledgements(
+private fun Acknowledgements(
onBack: () -> Unit,
onNavigate: (String) -> Unit,
isExpandedScreen: Boolean,
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Contributors.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Contributors.kt
index 76c0990c29a..9d97ab59b16 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Contributors.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Contributors.kt
@@ -20,6 +20,8 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
import app.lawnchair.lawnicons.R
import app.lawnchair.lawnicons.model.GitHubContributor
import app.lawnchair.lawnicons.ui.components.ContributorRow
@@ -33,11 +35,25 @@ import app.lawnchair.lawnicons.viewmodel.ContributorsUiState
import app.lawnchair.lawnicons.viewmodel.ContributorsViewModel
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
+import kotlinx.serialization.Serializable
-const val CONTRIBUTOR_URL = "${Constants.GITHUB}/graphs/contributors"
+@Serializable
+data object Contributors
+
+fun NavGraphBuilder.contributorsDestination(
+ onBack: () -> Unit,
+ isExpandedScreen: Boolean,
+) {
+ composable {
+ Contributors(
+ onBack = onBack,
+ isExpandedScreen = isExpandedScreen,
+ )
+ }
+}
@Composable
-fun Contributors(
+private fun Contributors(
onBack: () -> Unit,
isExpandedScreen: Boolean,
modifier: Modifier = Modifier,
@@ -158,13 +174,14 @@ private fun ContributorListError(
SideEffect {
onBack()
// we might be rate-limited, open the web ui instead
- val website =
- Uri.parse(CONTRIBUTOR_URL)
+ val website = Uri.parse(CONTRIBUTOR_URL)
val intent = Intent(Intent.ACTION_VIEW, website)
context.startActivity(intent)
}
}
+private const val CONTRIBUTOR_URL = "${Constants.GITHUB}/graphs/contributors"
+
@PreviewLawnicons
@Composable
private fun ContributorsScreenPreview() {
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
index 7fcf0b211ae..e4af608c7db 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
@@ -24,6 +24,8 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
import app.lawnchair.lawnicons.model.IconInfo
import app.lawnchair.lawnicons.model.SearchMode
import app.lawnchair.lawnicons.ui.components.home.HomeBottomBar
@@ -39,11 +41,31 @@ import app.lawnchair.lawnicons.ui.util.PreviewLawnicons
import app.lawnchair.lawnicons.ui.util.SampleData
import app.lawnchair.lawnicons.viewmodel.LawniconsViewModel
import kotlinx.collections.immutable.toImmutableList
+import kotlinx.serialization.Serializable
+
+@Serializable
+data object Home
+
+fun NavGraphBuilder.homeDestination(
+ isExpandedScreen: Boolean,
+ isIconPicker: Boolean,
+ onNavigate: () -> Unit,
+ onSendResult: (IconInfo) -> Unit,
+) {
+ composable {
+ Home(
+ onNavigate = onNavigate,
+ isExpandedScreen = isExpandedScreen,
+ isIconPicker = isIconPicker,
+ onSendResult = onSendResult,
+ )
+ }
+}
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@Composable
-fun Home(
+private fun Home(
onNavigate: () -> Unit,
onSendResult: (IconInfo) -> Unit,
isExpandedScreen: Boolean,
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/Destinations.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/Destinations.kt
deleted file mode 100644
index bcc6846dac0..00000000000
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/Destinations.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package app.lawnchair.lawnicons.ui.util
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-object Home
-
-@Serializable
-object About
-
-@Serializable
-object Acknowledgements
-
-@Serializable
-object Contributors
-
-@Serializable
-data class Acknowledgement(val id: String)
From a966f8502aab0507d40eeb3d20a2a7eb2d7a3b89 Mon Sep 17 00:00:00 2001
From: Zongle Wang
Date: Fri, 6 Sep 2024 06:40:47 -0400
Subject: [PATCH 105/144] Mark stable classes and enable Compose Compiler
reports (#2280)
* Remove org.jetbrains.kotlinx:kotlinx-collections-immutable
* Enable stabilityConfigurationFile and reportsDestination
https://developer.android.com/develop/ui/compose/performance/stability/fix#configuration-file
---
app/build.gradle.kts | 6 +++++-
app/compose_compiler_config.conf | 7 +++++++
.../app/lawnchair/lawnicons/model/IconInfoModel.kt | 6 ++----
.../lawnchair/lawnicons/model/IconRequestModel.kt | 4 +---
.../lawnicons/repository/IconRepository.kt | 13 +++++--------
.../lawnicons/ui/components/home/IconPreviewGrid.kt | 3 +--
.../ui/components/home/search/SearchContents.kt | 5 ++---
.../lawnicons/ui/destination/Contributors.kt | 8 +++-----
.../app/lawnchair/lawnicons/ui/destination/Home.kt | 3 +--
.../app/lawnchair/lawnicons/ui/util/PreviewUtils.kt | 3 +--
.../lawnicons/viewmodel/ContributorsViewModel.kt | 8 +++-----
11 files changed, 31 insertions(+), 35 deletions(-)
create mode 100644 app/compose_compiler_config.conf
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 1fb5382ed6d..ca1b7c15666 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -131,6 +131,11 @@ tasks.withType().configureEach {
dependsOn(projects.svgProcessor.dependencyProject.tasks.named("run"))
}
+composeCompiler {
+ stabilityConfigurationFile = layout.projectDirectory.file("compose_compiler_config.conf")
+ reportsDestination = layout.buildDirectory.dir("compose_build_reports")
+}
+
licensee {
allow("Apache-2.0")
allow("MIT")
@@ -153,7 +158,6 @@ dependencies {
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.5")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.2")
- implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.8")
val hiltVersion = "2.52"
implementation("com.google.dagger:hilt-android:$hiltVersion")
diff --git a/app/compose_compiler_config.conf b/app/compose_compiler_config.conf
new file mode 100644
index 00000000000..ac70d690a9f
--- /dev/null
+++ b/app/compose_compiler_config.conf
@@ -0,0 +1,7 @@
+kotlin.collections.*
+kotlin.time.Duration
+
+kotlinx.coroutines.CoroutineScope
+
+// All models should be stable.
+app.lawnchair.lawnicons.model.*
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconInfoModel.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconInfoModel.kt
index 716402f815f..1d918d14b3b 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconInfoModel.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconInfoModel.kt
@@ -1,7 +1,5 @@
package app.lawnchair.lawnicons.model
-import kotlinx.collections.immutable.ImmutableList
-
/**
* Data class to hold information about icons.
*
@@ -9,6 +7,6 @@ import kotlinx.collections.immutable.ImmutableList
* @property iconCount The total number of icons.
*/
data class IconInfoModel(
- val iconInfo: ImmutableList,
- val iconCount: Int,
+ val iconInfo: List = emptyList(),
+ val iconCount: Int = 0,
)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconRequestModel.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconRequestModel.kt
index d26f7f76115..4de30e1ef5b 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconRequestModel.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/model/IconRequestModel.kt
@@ -1,13 +1,11 @@
package app.lawnchair.lawnicons.model
-import kotlinx.collections.immutable.ImmutableList
-
data class IconRequest(
val label: String,
val componentName: String,
)
data class IconRequestModel(
- val list: ImmutableList,
+ val list: List,
val iconCount: Int,
)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt
index c03ddb1cf28..1de7e4e4ee8 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/IconRepository.kt
@@ -12,9 +12,6 @@ import app.lawnchair.lawnicons.model.splitByComponentName
import app.lawnchair.lawnicons.util.getIconInfo
import app.lawnchair.lawnicons.util.getSystemIconInfoAppfilter
import javax.inject.Inject
-import kotlinx.collections.immutable.persistentListOf
-import kotlinx.collections.immutable.toImmutableList
-import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
@@ -36,10 +33,10 @@ class IconRepositoryImpl @Inject constructor(application: Application) : IconRep
private val coroutineScope = CoroutineScope(Dispatchers.IO)
- private val _iconInfoModel = MutableStateFlow(IconInfoModel(persistentListOf(), 0))
+ private val _iconInfoModel = MutableStateFlow(IconInfoModel())
override val iconInfoModel = _iconInfoModel.asStateFlow()
- private val _searchedIconInfoModel = MutableStateFlow(IconInfoModel(persistentListOf(), 0))
+ private val _searchedIconInfoModel = MutableStateFlow(IconInfoModel())
override val searchedIconInfoModel = _searchedIconInfoModel.asStateFlow()
override val iconRequestList = MutableStateFlow(value = null)
@@ -51,7 +48,7 @@ class IconRepositoryImpl @Inject constructor(application: Application) : IconRep
val iconCount = groupedIcons.size
_iconInfoModel.value = IconInfoModel(
- iconInfo = iconList.toPersistentList(),
+ iconInfo = iconList,
iconCount = iconCount,
)
_searchedIconInfoModel.value = _iconInfoModel.value
@@ -92,7 +89,7 @@ class IconRepositoryImpl @Inject constructor(application: Application) : IconRep
),
).map { searchInfo ->
searchInfo.iconInfo
- }.toPersistentList()
+ }
_searchedIconInfoModel.value = IconInfoModel(
iconCount = _searchedIconInfoModel.value.iconCount,
@@ -127,7 +124,7 @@ class IconRepositoryImpl @Inject constructor(application: Application) : IconRep
}
iconRequestList.value = IconRequestModel(
- list = commonItems.toImmutableList(),
+ list = commonItems,
iconCount = commonItems.size,
)
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
index 98284cb58a6..3821e3e60fb 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
@@ -57,7 +57,6 @@ import app.lawnchair.lawnicons.ui.util.PreviewLawnicons
import app.lawnchair.lawnicons.ui.util.SampleData
import app.lawnchair.lawnicons.ui.util.toPaddingValues
import app.lawnchair.lawnicons.util.appIcon
-import kotlinx.collections.immutable.ImmutableList
import my.nanihadesuka.compose.InternalLazyVerticalGridScrollbar
import my.nanihadesuka.compose.ScrollbarSelectionMode
import my.nanihadesuka.compose.ScrollbarSettings
@@ -65,7 +64,7 @@ import my.nanihadesuka.compose.ScrollbarSettings
@Composable
@ExperimentalFoundationApi
fun IconPreviewGrid(
- iconInfo: ImmutableList,
+ iconInfo: List,
isExpandedScreen: Boolean,
onSendResult: (IconInfo) -> Unit,
modifier: Modifier = Modifier,
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
index bd919f75d08..62b18cf9e61 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchContents.kt
@@ -43,14 +43,13 @@ import app.lawnchair.lawnicons.model.SearchMode
import app.lawnchair.lawnicons.model.getFirstLabelAndComponent
import app.lawnchair.lawnicons.ui.components.home.IconInfoSheet
import app.lawnchair.lawnicons.ui.components.home.IconPreview
-import kotlinx.collections.immutable.ImmutableList
@Composable
fun SearchContents(
searchTerm: String,
searchMode: SearchMode,
onModeChange: (SearchMode) -> Unit,
- iconInfo: ImmutableList,
+ iconInfo: List,
modifier: Modifier = Modifier,
onSendResult: (IconInfo) -> Unit = {},
) {
@@ -167,7 +166,7 @@ fun SearchContents(
}
@Composable
-private fun IconInfoListItem(iconInfo: ImmutableList) {
+private fun IconInfoListItem(iconInfo: List) {
Column(
modifier = Modifier
.fillMaxWidth()
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Contributors.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Contributors.kt
index 9d97ab59b16..124c0c8b5a1 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Contributors.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Contributors.kt
@@ -33,8 +33,6 @@ import app.lawnchair.lawnicons.ui.util.Constants
import app.lawnchair.lawnicons.ui.util.PreviewLawnicons
import app.lawnchair.lawnicons.viewmodel.ContributorsUiState
import app.lawnchair.lawnicons.viewmodel.ContributorsViewModel
-import kotlinx.collections.immutable.ImmutableList
-import kotlinx.collections.immutable.persistentListOf
import kotlinx.serialization.Serializable
@Serializable
@@ -111,7 +109,7 @@ fun Contributors(
@Composable
private fun ContributorList(
- contributors: ImmutableList,
+ contributors: List,
modifier: Modifier = Modifier,
contentPadding: PaddingValues = PaddingValues(),
) {
@@ -185,7 +183,7 @@ private const val CONTRIBUTOR_URL = "${Constants.GITHUB}/graphs/contributors"
@PreviewLawnicons
@Composable
private fun ContributorsScreenPreview() {
- val contributors = persistentListOf(
+ val contributors = listOf(
GitHubContributor(
id = 1,
login = "Example",
@@ -219,7 +217,7 @@ private fun ContributorsScreenLoadingPreview() {
@PreviewLawnicons
@Composable
private fun ContributorListPreview() {
- val contributors = persistentListOf(
+ val contributors = listOf(
GitHubContributor(
id = 1,
login = "Example",
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
index e4af608c7db..a257463e19f 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
@@ -40,7 +40,6 @@ import app.lawnchair.lawnicons.ui.theme.LawniconsTheme
import app.lawnchair.lawnicons.ui.util.PreviewLawnicons
import app.lawnchair.lawnicons.ui.util.SampleData
import app.lawnchair.lawnicons.viewmodel.LawniconsViewModel
-import kotlinx.collections.immutable.toImmutableList
import kotlinx.serialization.Serializable
@Serializable
@@ -196,7 +195,7 @@ private fun HomePreview() {
},
)
IconPreviewGrid(
- iconInfo = iconInfo.toImmutableList(),
+ iconInfo = iconInfo,
isExpandedScreen = false,
{},
Modifier,
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/PreviewUtils.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/PreviewUtils.kt
index 1e7543669b7..88f2c55b70b 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/PreviewUtils.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/PreviewUtils.kt
@@ -5,7 +5,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.Wallpapers
import app.lawnchair.lawnicons.model.IconInfo
import app.lawnchair.lawnicons.model.LabelAndComponent
-import kotlinx.collections.immutable.persistentListOf
@Preview(
name = "Normal",
@@ -39,7 +38,7 @@ object SampleData {
),
id = 1,
)
- val iconInfoList = persistentListOf(
+ val iconInfoList = listOf(
IconInfo(
drawableName = "@drawable/email",
componentNames = listOf(
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/ContributorsViewModel.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/ContributorsViewModel.kt
index f5dd2d57a52..c17cc568c0b 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/ContributorsViewModel.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/ContributorsViewModel.kt
@@ -7,8 +7,6 @@ import app.lawnchair.lawnicons.model.GitHubContributor
import app.lawnchair.lawnicons.repository.GitHubContributorsRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
-import kotlinx.collections.immutable.ImmutableList
-import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
@@ -19,7 +17,7 @@ import kotlinx.coroutines.launch
sealed interface ContributorsUiState {
data class Success(
- val contributors: ImmutableList,
+ val contributors: List,
) : ContributorsUiState
data object Loading : ContributorsUiState
@@ -28,7 +26,7 @@ sealed interface ContributorsUiState {
private data class ContributorsViewModelState(
val isRefreshing: Boolean,
- val contributors: ImmutableList? = null,
+ val contributors: List? = null,
val hasError: Boolean = false,
) {
fun toUiState(): ContributorsUiState = when {
@@ -63,7 +61,7 @@ class ContributorsViewModel @Inject constructor(
when {
result.isSuccess -> it.copy(
isRefreshing = false,
- contributors = result.getOrThrow().toPersistentList(),
+ contributors = result.getOrThrow(),
hasError = false,
)
From c53cc4a2770b2327c249953db9728eb53c21a6d5 Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Fri, 6 Sep 2024 14:38:55 +0300
Subject: [PATCH 106/144] New issue: Add a link to an existing icon (#2283)
* New issue: Add a link to an existing icon
* Update .github/ISSUE_TEMPLATE/config.yml
* Update .github/ISSUE_TEMPLATE/config.yml
Co-authored-by: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
---------
Co-authored-by: Zongle Wang
Co-authored-by: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
---
.github/ISSUE_TEMPLATE/config.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 637761d9d26..214528c627e 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,5 +1,8 @@
blank_issues_enabled: false
contact_links:
+ - name: Link apps to existing icons
+ url: https://github.com/LawnchairLauncher/lawnicons/blob/develop/CONTRIBUTING.md#adding-an-icon-to-lawnicons
+ about: Learn more about linking an app to an existing icon and making a PR to contribute to Lawnicons.
- name: Icon Request
url: https://forms.gle/xt7sJhgWEasuo9TR9
about: Please request your icons in this form.
From dbd28e324991693b7c73bffc2b641c057cf66c35 Mon Sep 17 00:00:00 2001
From: juman-y <80329028+juman-y@users.noreply.github.com>
Date: Fri, 6 Sep 2024 14:52:27 +0000
Subject: [PATCH 107/144] Add Infinity for Reddit link (#2309)
---
app/assets/appfilter.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index d58db01649e..14c6fee4060 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -4573,6 +4573,7 @@
+
From 0e5ce9c3d90e431a6c04304cc7852017c1a26502 Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Sun, 8 Sep 2024 02:22:58 +0300
Subject: [PATCH 108/144] [Barter 5] +100 icons: Bybit, My Huawei, Wa Enhancer
(#2310)
---
app/assets/appfilter.xml | 103 +++++++++++++++++++++++++
svgs/_1weather.svg | 1 +
svgs/adda247.svg | 1 +
svgs/adidas.svg | 2 +-
svgs/adidas_running.svg | 1 +
svgs/agc_toolkit.svg | 1 +
svgs/ai_wallpapers.svg | 1 +
svgs/ar_art_projector.svg | 1 +
svgs/blackmagic_camera.svg | 1 +
svgs/block_blast.svg | 1 +
svgs/brilliant.svg | 1 +
svgs/bybit.svg | 1 +
svgs/calculator_you.svg | 1 +
svgs/capturesposed.svg | 1 +
svgs/chalo.svg | 1 +
svgs/clearscore.svg | 1 +
svgs/click_to_chat.svg | 1 +
svgs/crayon_icons.svg | 1 +
svgs/day_one_journal.svg | 1 +
svgs/dr_web.svg | 1 +
svgs/evernote.svg | 1 +
svgs/flow_free.svg | 1 +
svgs/folax.svg | 1 +
svgs/fold.svg | 1 +
svgs/g_cpu.svg | 1 +
svgs/geometry_dash_meltdown.svg | 1 +
svgs/giphy.svg | 1 +
svgs/glassdoor.svg | 1 +
svgs/healthy_battery_charging.svg | 1 +
svgs/huawei_appassistant.svg | 1 +
svgs/huawei_optimizer.svg | 1 +
svgs/huawei_themes.svg | 1 +
svgs/huawei_weather.svg | 1 +
svgs/hyperos_downloader.svg | 1 +
svgs/hypic.svg | 1 +
svgs/iliad_visual_voicemail.svg | 1 +
svgs/intel_unison.svg | 1 +
svgs/iyps.svg | 1 +
svgs/jetpack_joyride.svg | 1 +
svgs/jumia.svg | 1 +
svgs/koda_for_kustom.svg | 1 +
svgs/livescore.svg | 1 +
svgs/mach.svg | 1 +
svgs/magisk_module_repo_loader.svg | 1 +
svgs/mail_ru.svg | 1 +
svgs/mcpedl_for_minecraft.svg | 1 +
svgs/mi_mover.svg | 1 +
svgs/mi_personal_flow.svg | 1 +
svgs/mobile_data_consumption.svg | 1 +
svgs/mobile_jkn.svg | 1 +
svgs/modern_warships.svg | 1 +
svgs/modo.svg | 1 +
svgs/moto_unplugged.svg | 1 +
svgs/musclewiki.svg | 1 +
svgs/muslim_pro.svg | 1 +
svgs/my_apps_time.svg | 1 +
svgs/my_huawei.svg | 1 +
svgs/my_zong.svg | 1 +
svgs/national_train_enquiry_system.svg | 1 +
svgs/native_alpha_plus.svg | 1 +
svgs/nays.svg | 1 +
svgs/nothing_icons.svg | 1 +
svgs/octohide_vpn.svg | 1 +
svgs/offline_games.svg | 1 +
svgs/onecard.svg | 1 +
svgs/onescore.svg | 1 +
svgs/overmorrow_weather.svg | 1 +
svgs/pixel_launcher.svg | 1 +
svgs/plato.svg | 1 +
svgs/playhub.svg | 1 +
svgs/qanda.svg | 1 +
svgs/qralarm.svg | 1 +
svgs/quikshort.svg | 1 +
svgs/rappi.svg | 1 +
svgs/regain.svg | 1 +
svgs/ring.svg | 1 +
svgs/round_sync.svg | 1 +
svgs/screen_orientation_control.svg | 1 +
svgs/sd_maid.svg | 2 +-
svgs/sd_maid_1_pro.svg | 1 +
svgs/shelf.svg | 1 +
svgs/simosa.svg | 1 +
svgs/spin_the_wheel.svg | 1 +
svgs/storage_saver.svg | 1 +
svgs/super_money.svg | 1 +
svgs/supreme_duelist.svg | 1 +
svgs/syphon.svg | 1 +
svgs/t_mobile_visual_voicemail.svg | 1 +
svgs/tecno_spot.svg | 1 +
svgs/ten_ten.svg | 1 +
svgs/thunder_vpn.svg | 1 +
svgs/ts_news_plus.svg | 1 +
svgs/update_me.svg | 1 +
svgs/v_appstore.svg | 1 +
svgs/vivo_feedback.svg | 1 +
svgs/wa_enhancer.svg | 1 +
svgs/wear_installer_2.svg | 1 +
svgs/welife.svg | 1 +
svgs/work_log.svg | 1 +
svgs/x_vpn.svg | 1 +
svgs/yearly_progress.svg | 1 +
svgs/youtube_adaway.svg | 1 +
svgs/zenless_zone_zero.svg | 1 +
103 files changed, 205 insertions(+), 2 deletions(-)
create mode 100644 svgs/_1weather.svg
create mode 100644 svgs/adda247.svg
create mode 100644 svgs/adidas_running.svg
create mode 100644 svgs/agc_toolkit.svg
create mode 100644 svgs/ai_wallpapers.svg
create mode 100644 svgs/ar_art_projector.svg
create mode 100644 svgs/blackmagic_camera.svg
create mode 100644 svgs/block_blast.svg
create mode 100644 svgs/brilliant.svg
create mode 100644 svgs/bybit.svg
create mode 100644 svgs/calculator_you.svg
create mode 100644 svgs/capturesposed.svg
create mode 100644 svgs/chalo.svg
create mode 100644 svgs/clearscore.svg
create mode 100644 svgs/click_to_chat.svg
create mode 100644 svgs/crayon_icons.svg
create mode 100644 svgs/day_one_journal.svg
create mode 100644 svgs/dr_web.svg
create mode 100644 svgs/evernote.svg
create mode 100644 svgs/flow_free.svg
create mode 100644 svgs/folax.svg
create mode 100644 svgs/fold.svg
create mode 100644 svgs/g_cpu.svg
create mode 100644 svgs/geometry_dash_meltdown.svg
create mode 100644 svgs/giphy.svg
create mode 100644 svgs/glassdoor.svg
create mode 100644 svgs/healthy_battery_charging.svg
create mode 100644 svgs/huawei_appassistant.svg
create mode 100644 svgs/huawei_optimizer.svg
create mode 100644 svgs/huawei_themes.svg
create mode 100644 svgs/huawei_weather.svg
create mode 100644 svgs/hyperos_downloader.svg
create mode 100644 svgs/hypic.svg
create mode 100644 svgs/iliad_visual_voicemail.svg
create mode 100644 svgs/intel_unison.svg
create mode 100644 svgs/iyps.svg
create mode 100644 svgs/jetpack_joyride.svg
create mode 100644 svgs/jumia.svg
create mode 100644 svgs/koda_for_kustom.svg
create mode 100644 svgs/livescore.svg
create mode 100644 svgs/mach.svg
create mode 100644 svgs/magisk_module_repo_loader.svg
create mode 100644 svgs/mail_ru.svg
create mode 100644 svgs/mcpedl_for_minecraft.svg
create mode 100644 svgs/mi_mover.svg
create mode 100644 svgs/mi_personal_flow.svg
create mode 100644 svgs/mobile_data_consumption.svg
create mode 100644 svgs/mobile_jkn.svg
create mode 100644 svgs/modern_warships.svg
create mode 100644 svgs/modo.svg
create mode 100644 svgs/moto_unplugged.svg
create mode 100644 svgs/musclewiki.svg
create mode 100644 svgs/muslim_pro.svg
create mode 100644 svgs/my_apps_time.svg
create mode 100644 svgs/my_huawei.svg
create mode 100644 svgs/my_zong.svg
create mode 100644 svgs/national_train_enquiry_system.svg
create mode 100644 svgs/native_alpha_plus.svg
create mode 100644 svgs/nays.svg
create mode 100644 svgs/nothing_icons.svg
create mode 100644 svgs/octohide_vpn.svg
create mode 100644 svgs/offline_games.svg
create mode 100644 svgs/onecard.svg
create mode 100644 svgs/onescore.svg
create mode 100644 svgs/overmorrow_weather.svg
create mode 100644 svgs/pixel_launcher.svg
create mode 100644 svgs/plato.svg
create mode 100644 svgs/playhub.svg
create mode 100644 svgs/qanda.svg
create mode 100644 svgs/qralarm.svg
create mode 100644 svgs/quikshort.svg
create mode 100644 svgs/rappi.svg
create mode 100644 svgs/regain.svg
create mode 100644 svgs/ring.svg
create mode 100644 svgs/round_sync.svg
create mode 100644 svgs/screen_orientation_control.svg
create mode 100644 svgs/sd_maid_1_pro.svg
create mode 100644 svgs/shelf.svg
create mode 100644 svgs/simosa.svg
create mode 100644 svgs/spin_the_wheel.svg
create mode 100644 svgs/storage_saver.svg
create mode 100644 svgs/super_money.svg
create mode 100644 svgs/supreme_duelist.svg
create mode 100644 svgs/syphon.svg
create mode 100644 svgs/t_mobile_visual_voicemail.svg
create mode 100644 svgs/tecno_spot.svg
create mode 100644 svgs/ten_ten.svg
create mode 100644 svgs/thunder_vpn.svg
create mode 100644 svgs/ts_news_plus.svg
create mode 100644 svgs/update_me.svg
create mode 100644 svgs/v_appstore.svg
create mode 100644 svgs/vivo_feedback.svg
create mode 100644 svgs/wa_enhancer.svg
create mode 100644 svgs/wear_installer_2.svg
create mode 100644 svgs/welife.svg
create mode 100644 svgs/work_log.svg
create mode 100644 svgs/x_vpn.svg
create mode 100644 svgs/yearly_progress.svg
create mode 100644 svgs/youtube_adaway.svg
create mode 100644 svgs/zenless_zone_zero.svg
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index 14c6fee4060..578bdb4be14 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -61,6 +61,7 @@
+
@@ -175,6 +176,7 @@
+
@@ -191,6 +193,7 @@
+
@@ -233,6 +236,7 @@
+
@@ -246,6 +250,7 @@
+
@@ -649,6 +654,7 @@
+
@@ -1111,6 +1117,7 @@
+
@@ -1137,6 +1144,7 @@
+
@@ -1295,6 +1303,7 @@
+
@@ -1434,6 +1443,7 @@
+
@@ -1507,6 +1517,7 @@
+
@@ -1760,6 +1771,7 @@
+
@@ -1837,6 +1849,7 @@
+
@@ -1974,9 +1987,11 @@
+
+
@@ -2327,6 +2342,7 @@
+
@@ -2431,6 +2447,7 @@
+
@@ -2791,6 +2808,7 @@
+
@@ -3087,6 +3105,7 @@
+
@@ -3443,6 +3462,7 @@
+
@@ -3491,6 +3511,8 @@
+
+
@@ -3636,6 +3658,7 @@
+
@@ -3796,6 +3819,7 @@
+
@@ -3833,6 +3857,7 @@
+
@@ -3841,6 +3866,7 @@
+
@@ -4244,6 +4270,7 @@
+
@@ -4376,6 +4403,7 @@
+
@@ -4386,11 +4414,14 @@
+
+
+
@@ -4408,6 +4439,8 @@
+
+
@@ -4495,6 +4528,7 @@
+
@@ -4642,6 +4676,7 @@
+
@@ -4717,6 +4752,7 @@
+
@@ -4749,6 +4785,7 @@
+
@@ -4792,6 +4829,7 @@
+
@@ -5036,6 +5074,7 @@
+
@@ -5322,6 +5361,7 @@
+
@@ -5400,6 +5440,7 @@
+
@@ -5440,6 +5481,7 @@
+
@@ -5455,6 +5497,7 @@
+
@@ -5589,6 +5632,7 @@
+
@@ -5803,6 +5847,7 @@
+
@@ -5811,6 +5856,7 @@
+
@@ -6014,8 +6060,10 @@
+
+
@@ -6031,6 +6079,8 @@
+
+
@@ -6123,6 +6173,7 @@
+
@@ -6168,6 +6219,7 @@
+
@@ -6211,6 +6263,7 @@
+
@@ -6245,6 +6298,7 @@
+
@@ -6267,6 +6321,7 @@
+
@@ -6343,6 +6398,7 @@
+
@@ -6480,8 +6536,10 @@
+
+
@@ -6495,6 +6553,7 @@
+
@@ -6721,6 +6780,7 @@
+
@@ -6859,6 +6919,7 @@
+
@@ -6877,6 +6938,7 @@
+
@@ -6979,6 +7041,7 @@
+
@@ -7014,6 +7077,7 @@
+
@@ -7157,6 +7221,7 @@
+
@@ -7643,6 +7708,9 @@
+
+
+
@@ -7731,11 +7799,13 @@
+
+
@@ -8007,6 +8077,7 @@
+
@@ -8069,6 +8140,7 @@
+
@@ -8096,6 +8168,7 @@
+
@@ -8181,6 +8254,7 @@
+
@@ -8308,6 +8382,7 @@
+
@@ -8409,6 +8484,7 @@
+
@@ -8456,6 +8532,7 @@
+
@@ -8714,6 +8791,7 @@
+
@@ -8733,6 +8811,7 @@
+
@@ -8905,6 +8984,7 @@
+
@@ -9022,6 +9102,7 @@
+
@@ -9704,6 +9785,7 @@
+
@@ -9860,6 +9942,7 @@
+
@@ -9938,6 +10021,7 @@
+
@@ -9952,6 +10036,7 @@
+
@@ -10025,6 +10110,7 @@
+
@@ -10038,6 +10124,7 @@
+
@@ -10141,6 +10228,7 @@
+
@@ -10229,6 +10317,7 @@
+
@@ -10541,6 +10630,7 @@
+
@@ -10805,6 +10895,7 @@
+
@@ -11000,6 +11091,7 @@
+
@@ -11046,6 +11138,7 @@
+
@@ -11234,6 +11327,7 @@
+
@@ -11335,6 +11429,8 @@
+
+
@@ -11411,6 +11507,7 @@
+
@@ -11456,6 +11553,7 @@
+
@@ -11703,6 +11801,7 @@
+
@@ -11758,6 +11857,7 @@
+
@@ -11848,6 +11948,7 @@
+
@@ -11900,6 +12001,7 @@
+
@@ -12006,6 +12108,7 @@
+
diff --git a/svgs/_1weather.svg b/svgs/_1weather.svg
new file mode 100644
index 00000000000..73f5c225423
--- /dev/null
+++ b/svgs/_1weather.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/adda247.svg b/svgs/adda247.svg
new file mode 100644
index 00000000000..9d79a897481
--- /dev/null
+++ b/svgs/adda247.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/adidas.svg b/svgs/adidas.svg
index 146895ce61f..7eba9ca5bc1 100644
--- a/svgs/adidas.svg
+++ b/svgs/adidas.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/adidas_running.svg b/svgs/adidas_running.svg
new file mode 100644
index 00000000000..09ba227fed1
--- /dev/null
+++ b/svgs/adidas_running.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/agc_toolkit.svg b/svgs/agc_toolkit.svg
new file mode 100644
index 00000000000..f45f4cfa5b1
--- /dev/null
+++ b/svgs/agc_toolkit.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/ai_wallpapers.svg b/svgs/ai_wallpapers.svg
new file mode 100644
index 00000000000..b104047f117
--- /dev/null
+++ b/svgs/ai_wallpapers.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/ar_art_projector.svg b/svgs/ar_art_projector.svg
new file mode 100644
index 00000000000..df06137d7a6
--- /dev/null
+++ b/svgs/ar_art_projector.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/blackmagic_camera.svg b/svgs/blackmagic_camera.svg
new file mode 100644
index 00000000000..0bcfc9d03be
--- /dev/null
+++ b/svgs/blackmagic_camera.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/block_blast.svg b/svgs/block_blast.svg
new file mode 100644
index 00000000000..10c50a35835
--- /dev/null
+++ b/svgs/block_blast.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/brilliant.svg b/svgs/brilliant.svg
new file mode 100644
index 00000000000..f89db8c850f
--- /dev/null
+++ b/svgs/brilliant.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/bybit.svg b/svgs/bybit.svg
new file mode 100644
index 00000000000..526e9b2f431
--- /dev/null
+++ b/svgs/bybit.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/calculator_you.svg b/svgs/calculator_you.svg
new file mode 100644
index 00000000000..2eb4ba38010
--- /dev/null
+++ b/svgs/calculator_you.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/capturesposed.svg b/svgs/capturesposed.svg
new file mode 100644
index 00000000000..1c7547377a9
--- /dev/null
+++ b/svgs/capturesposed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/chalo.svg b/svgs/chalo.svg
new file mode 100644
index 00000000000..e35e3f322a3
--- /dev/null
+++ b/svgs/chalo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/clearscore.svg b/svgs/clearscore.svg
new file mode 100644
index 00000000000..734ca2aa2fa
--- /dev/null
+++ b/svgs/clearscore.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/click_to_chat.svg b/svgs/click_to_chat.svg
new file mode 100644
index 00000000000..89aa36ab70e
--- /dev/null
+++ b/svgs/click_to_chat.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/crayon_icons.svg b/svgs/crayon_icons.svg
new file mode 100644
index 00000000000..56fe80a324e
--- /dev/null
+++ b/svgs/crayon_icons.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/day_one_journal.svg b/svgs/day_one_journal.svg
new file mode 100644
index 00000000000..2c28b98e7f1
--- /dev/null
+++ b/svgs/day_one_journal.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/dr_web.svg b/svgs/dr_web.svg
new file mode 100644
index 00000000000..5e164359114
--- /dev/null
+++ b/svgs/dr_web.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/evernote.svg b/svgs/evernote.svg
new file mode 100644
index 00000000000..75204bfac9c
--- /dev/null
+++ b/svgs/evernote.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/flow_free.svg b/svgs/flow_free.svg
new file mode 100644
index 00000000000..2c519da16e8
--- /dev/null
+++ b/svgs/flow_free.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/folax.svg b/svgs/folax.svg
new file mode 100644
index 00000000000..740fb019012
--- /dev/null
+++ b/svgs/folax.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/fold.svg b/svgs/fold.svg
new file mode 100644
index 00000000000..6b0a11eea67
--- /dev/null
+++ b/svgs/fold.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/g_cpu.svg b/svgs/g_cpu.svg
new file mode 100644
index 00000000000..d836f349f28
--- /dev/null
+++ b/svgs/g_cpu.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/geometry_dash_meltdown.svg b/svgs/geometry_dash_meltdown.svg
new file mode 100644
index 00000000000..b4643f72b98
--- /dev/null
+++ b/svgs/geometry_dash_meltdown.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/giphy.svg b/svgs/giphy.svg
new file mode 100644
index 00000000000..95c743c2634
--- /dev/null
+++ b/svgs/giphy.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/glassdoor.svg b/svgs/glassdoor.svg
new file mode 100644
index 00000000000..49a9b3e724f
--- /dev/null
+++ b/svgs/glassdoor.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/healthy_battery_charging.svg b/svgs/healthy_battery_charging.svg
new file mode 100644
index 00000000000..c3e06eb71f4
--- /dev/null
+++ b/svgs/healthy_battery_charging.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/huawei_appassistant.svg b/svgs/huawei_appassistant.svg
new file mode 100644
index 00000000000..87f4af3432d
--- /dev/null
+++ b/svgs/huawei_appassistant.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/huawei_optimizer.svg b/svgs/huawei_optimizer.svg
new file mode 100644
index 00000000000..6249a3a8539
--- /dev/null
+++ b/svgs/huawei_optimizer.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/huawei_themes.svg b/svgs/huawei_themes.svg
new file mode 100644
index 00000000000..f6961a51619
--- /dev/null
+++ b/svgs/huawei_themes.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/huawei_weather.svg b/svgs/huawei_weather.svg
new file mode 100644
index 00000000000..86f059003c3
--- /dev/null
+++ b/svgs/huawei_weather.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/hyperos_downloader.svg b/svgs/hyperos_downloader.svg
new file mode 100644
index 00000000000..511689e6893
--- /dev/null
+++ b/svgs/hyperos_downloader.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/hypic.svg b/svgs/hypic.svg
new file mode 100644
index 00000000000..20637a423bc
--- /dev/null
+++ b/svgs/hypic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/iliad_visual_voicemail.svg b/svgs/iliad_visual_voicemail.svg
new file mode 100644
index 00000000000..bd6b0f456b6
--- /dev/null
+++ b/svgs/iliad_visual_voicemail.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/intel_unison.svg b/svgs/intel_unison.svg
new file mode 100644
index 00000000000..0355df5d09e
--- /dev/null
+++ b/svgs/intel_unison.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/iyps.svg b/svgs/iyps.svg
new file mode 100644
index 00000000000..be6b77db263
--- /dev/null
+++ b/svgs/iyps.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/jetpack_joyride.svg b/svgs/jetpack_joyride.svg
new file mode 100644
index 00000000000..799be1c440e
--- /dev/null
+++ b/svgs/jetpack_joyride.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/jumia.svg b/svgs/jumia.svg
new file mode 100644
index 00000000000..26e266afe84
--- /dev/null
+++ b/svgs/jumia.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/koda_for_kustom.svg b/svgs/koda_for_kustom.svg
new file mode 100644
index 00000000000..da0d5f4c4f1
--- /dev/null
+++ b/svgs/koda_for_kustom.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/livescore.svg b/svgs/livescore.svg
new file mode 100644
index 00000000000..b21a4b3057a
--- /dev/null
+++ b/svgs/livescore.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/mach.svg b/svgs/mach.svg
new file mode 100644
index 00000000000..c23dcddc2b5
--- /dev/null
+++ b/svgs/mach.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/magisk_module_repo_loader.svg b/svgs/magisk_module_repo_loader.svg
new file mode 100644
index 00000000000..48fb05f52a1
--- /dev/null
+++ b/svgs/magisk_module_repo_loader.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/mail_ru.svg b/svgs/mail_ru.svg
new file mode 100644
index 00000000000..a4d6180d7c0
--- /dev/null
+++ b/svgs/mail_ru.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/mcpedl_for_minecraft.svg b/svgs/mcpedl_for_minecraft.svg
new file mode 100644
index 00000000000..543c03ce8b7
--- /dev/null
+++ b/svgs/mcpedl_for_minecraft.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/mi_mover.svg b/svgs/mi_mover.svg
new file mode 100644
index 00000000000..098a152db11
--- /dev/null
+++ b/svgs/mi_mover.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/mi_personal_flow.svg b/svgs/mi_personal_flow.svg
new file mode 100644
index 00000000000..08073074d65
--- /dev/null
+++ b/svgs/mi_personal_flow.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/mobile_data_consumption.svg b/svgs/mobile_data_consumption.svg
new file mode 100644
index 00000000000..1919c9fb5d0
--- /dev/null
+++ b/svgs/mobile_data_consumption.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/mobile_jkn.svg b/svgs/mobile_jkn.svg
new file mode 100644
index 00000000000..8a07922960d
--- /dev/null
+++ b/svgs/mobile_jkn.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/modern_warships.svg b/svgs/modern_warships.svg
new file mode 100644
index 00000000000..dc4a51d4fa1
--- /dev/null
+++ b/svgs/modern_warships.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/modo.svg b/svgs/modo.svg
new file mode 100644
index 00000000000..a6e04f5af64
--- /dev/null
+++ b/svgs/modo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/moto_unplugged.svg b/svgs/moto_unplugged.svg
new file mode 100644
index 00000000000..067ab7e7a95
--- /dev/null
+++ b/svgs/moto_unplugged.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/musclewiki.svg b/svgs/musclewiki.svg
new file mode 100644
index 00000000000..f6724970573
--- /dev/null
+++ b/svgs/musclewiki.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/muslim_pro.svg b/svgs/muslim_pro.svg
new file mode 100644
index 00000000000..0e05d5b7ecb
--- /dev/null
+++ b/svgs/muslim_pro.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/my_apps_time.svg b/svgs/my_apps_time.svg
new file mode 100644
index 00000000000..45293beaed2
--- /dev/null
+++ b/svgs/my_apps_time.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/my_huawei.svg b/svgs/my_huawei.svg
new file mode 100644
index 00000000000..5b3a4381fe4
--- /dev/null
+++ b/svgs/my_huawei.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/my_zong.svg b/svgs/my_zong.svg
new file mode 100644
index 00000000000..89247d037ce
--- /dev/null
+++ b/svgs/my_zong.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/national_train_enquiry_system.svg b/svgs/national_train_enquiry_system.svg
new file mode 100644
index 00000000000..a66beeaf857
--- /dev/null
+++ b/svgs/national_train_enquiry_system.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/native_alpha_plus.svg b/svgs/native_alpha_plus.svg
new file mode 100644
index 00000000000..07e6eec6834
--- /dev/null
+++ b/svgs/native_alpha_plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/nays.svg b/svgs/nays.svg
new file mode 100644
index 00000000000..f7839384e16
--- /dev/null
+++ b/svgs/nays.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/nothing_icons.svg b/svgs/nothing_icons.svg
new file mode 100644
index 00000000000..0f0a7e2ddc2
--- /dev/null
+++ b/svgs/nothing_icons.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/octohide_vpn.svg b/svgs/octohide_vpn.svg
new file mode 100644
index 00000000000..a80cd0ab3af
--- /dev/null
+++ b/svgs/octohide_vpn.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/offline_games.svg b/svgs/offline_games.svg
new file mode 100644
index 00000000000..14571dd09c0
--- /dev/null
+++ b/svgs/offline_games.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/onecard.svg b/svgs/onecard.svg
new file mode 100644
index 00000000000..a45de2db222
--- /dev/null
+++ b/svgs/onecard.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/onescore.svg b/svgs/onescore.svg
new file mode 100644
index 00000000000..f2dffb169c9
--- /dev/null
+++ b/svgs/onescore.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/overmorrow_weather.svg b/svgs/overmorrow_weather.svg
new file mode 100644
index 00000000000..e1d8307591d
--- /dev/null
+++ b/svgs/overmorrow_weather.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/pixel_launcher.svg b/svgs/pixel_launcher.svg
new file mode 100644
index 00000000000..bdde114429e
--- /dev/null
+++ b/svgs/pixel_launcher.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/plato.svg b/svgs/plato.svg
new file mode 100644
index 00000000000..3fdbc9170e9
--- /dev/null
+++ b/svgs/plato.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/playhub.svg b/svgs/playhub.svg
new file mode 100644
index 00000000000..c8cf49e12c7
--- /dev/null
+++ b/svgs/playhub.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/qanda.svg b/svgs/qanda.svg
new file mode 100644
index 00000000000..bbba90dd6a9
--- /dev/null
+++ b/svgs/qanda.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/qralarm.svg b/svgs/qralarm.svg
new file mode 100644
index 00000000000..5173d85eb75
--- /dev/null
+++ b/svgs/qralarm.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/quikshort.svg b/svgs/quikshort.svg
new file mode 100644
index 00000000000..8282914ad38
--- /dev/null
+++ b/svgs/quikshort.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/rappi.svg b/svgs/rappi.svg
new file mode 100644
index 00000000000..0e81de883c4
--- /dev/null
+++ b/svgs/rappi.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/regain.svg b/svgs/regain.svg
new file mode 100644
index 00000000000..62a01881c4f
--- /dev/null
+++ b/svgs/regain.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/ring.svg b/svgs/ring.svg
new file mode 100644
index 00000000000..73352365b6d
--- /dev/null
+++ b/svgs/ring.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/round_sync.svg b/svgs/round_sync.svg
new file mode 100644
index 00000000000..137be208ee7
--- /dev/null
+++ b/svgs/round_sync.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/screen_orientation_control.svg b/svgs/screen_orientation_control.svg
new file mode 100644
index 00000000000..98237f66cdc
--- /dev/null
+++ b/svgs/screen_orientation_control.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/sd_maid.svg b/svgs/sd_maid.svg
index ec63ca45e7e..0330bdad76c 100644
--- a/svgs/sd_maid.svg
+++ b/svgs/sd_maid.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/sd_maid_1_pro.svg b/svgs/sd_maid_1_pro.svg
new file mode 100644
index 00000000000..25f964a155b
--- /dev/null
+++ b/svgs/sd_maid_1_pro.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/shelf.svg b/svgs/shelf.svg
new file mode 100644
index 00000000000..91d8773159a
--- /dev/null
+++ b/svgs/shelf.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/simosa.svg b/svgs/simosa.svg
new file mode 100644
index 00000000000..8b3db5d882e
--- /dev/null
+++ b/svgs/simosa.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/spin_the_wheel.svg b/svgs/spin_the_wheel.svg
new file mode 100644
index 00000000000..0216c9173b4
--- /dev/null
+++ b/svgs/spin_the_wheel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/storage_saver.svg b/svgs/storage_saver.svg
new file mode 100644
index 00000000000..c3abd78d929
--- /dev/null
+++ b/svgs/storage_saver.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/super_money.svg b/svgs/super_money.svg
new file mode 100644
index 00000000000..70d9b16ead6
--- /dev/null
+++ b/svgs/super_money.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/supreme_duelist.svg b/svgs/supreme_duelist.svg
new file mode 100644
index 00000000000..e9b064b3031
--- /dev/null
+++ b/svgs/supreme_duelist.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/syphon.svg b/svgs/syphon.svg
new file mode 100644
index 00000000000..70e0cf85683
--- /dev/null
+++ b/svgs/syphon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/t_mobile_visual_voicemail.svg b/svgs/t_mobile_visual_voicemail.svg
new file mode 100644
index 00000000000..372e3256ff9
--- /dev/null
+++ b/svgs/t_mobile_visual_voicemail.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/tecno_spot.svg b/svgs/tecno_spot.svg
new file mode 100644
index 00000000000..92d0a14547f
--- /dev/null
+++ b/svgs/tecno_spot.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/ten_ten.svg b/svgs/ten_ten.svg
new file mode 100644
index 00000000000..ed449405a3a
--- /dev/null
+++ b/svgs/ten_ten.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/thunder_vpn.svg b/svgs/thunder_vpn.svg
new file mode 100644
index 00000000000..32b3e43780b
--- /dev/null
+++ b/svgs/thunder_vpn.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/ts_news_plus.svg b/svgs/ts_news_plus.svg
new file mode 100644
index 00000000000..4129d038433
--- /dev/null
+++ b/svgs/ts_news_plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/update_me.svg b/svgs/update_me.svg
new file mode 100644
index 00000000000..b3976388a60
--- /dev/null
+++ b/svgs/update_me.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/v_appstore.svg b/svgs/v_appstore.svg
new file mode 100644
index 00000000000..a929bcafef8
--- /dev/null
+++ b/svgs/v_appstore.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/vivo_feedback.svg b/svgs/vivo_feedback.svg
new file mode 100644
index 00000000000..dffc9762f75
--- /dev/null
+++ b/svgs/vivo_feedback.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/wa_enhancer.svg b/svgs/wa_enhancer.svg
new file mode 100644
index 00000000000..6a56ff7e16c
--- /dev/null
+++ b/svgs/wa_enhancer.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/wear_installer_2.svg b/svgs/wear_installer_2.svg
new file mode 100644
index 00000000000..b548064c5b5
--- /dev/null
+++ b/svgs/wear_installer_2.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/welife.svg b/svgs/welife.svg
new file mode 100644
index 00000000000..3fac32af04c
--- /dev/null
+++ b/svgs/welife.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/work_log.svg b/svgs/work_log.svg
new file mode 100644
index 00000000000..f1128a11233
--- /dev/null
+++ b/svgs/work_log.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/x_vpn.svg b/svgs/x_vpn.svg
new file mode 100644
index 00000000000..45a16d594a5
--- /dev/null
+++ b/svgs/x_vpn.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/yearly_progress.svg b/svgs/yearly_progress.svg
new file mode 100644
index 00000000000..a36aa65a5e1
--- /dev/null
+++ b/svgs/yearly_progress.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/youtube_adaway.svg b/svgs/youtube_adaway.svg
new file mode 100644
index 00000000000..e1482086706
--- /dev/null
+++ b/svgs/youtube_adaway.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/svgs/zenless_zone_zero.svg b/svgs/zenless_zone_zero.svg
new file mode 100644
index 00000000000..8a55dfc7174
--- /dev/null
+++ b/svgs/zenless_zone_zero.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
From ad7bb25b7c95f6ab8e802407eddf973d1ff22a77 Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Sun, 8 Sep 2024 10:02:32 +0300
Subject: [PATCH 109/144] +44 links (#2311)
* +44 links
* Minor fix
---
app/assets/appfilter.xml | 44 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index 578bdb4be14..27867659cda 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -61,6 +61,7 @@
+
@@ -1303,6 +1304,7 @@
+
@@ -1561,6 +1563,8 @@
+
+
@@ -1766,6 +1770,7 @@
+
@@ -2977,6 +2982,7 @@
+
@@ -3122,6 +3128,7 @@
+
@@ -3135,6 +3142,7 @@
+
@@ -3254,6 +3262,7 @@
+
@@ -3512,6 +3521,8 @@
+
+
@@ -3650,6 +3661,7 @@
+
@@ -4360,8 +4372,11 @@
+
+
+
@@ -4406,6 +4421,7 @@
+
@@ -4420,6 +4436,8 @@
+
+
@@ -4531,6 +4549,7 @@
+
@@ -5117,6 +5136,7 @@
+
@@ -5223,6 +5243,7 @@
+
@@ -5377,6 +5398,7 @@
+
@@ -5497,6 +5519,7 @@
+
@@ -5633,6 +5656,7 @@
+
@@ -5682,6 +5706,7 @@
+
@@ -6006,6 +6031,7 @@
+
@@ -6321,6 +6347,7 @@
+
@@ -6333,6 +6360,7 @@
+
@@ -6553,6 +6581,7 @@
+
@@ -7361,6 +7390,7 @@
+
@@ -7384,6 +7414,7 @@
+
@@ -7708,6 +7739,7 @@
+
@@ -8166,6 +8198,7 @@
+
@@ -9102,6 +9135,7 @@
+
@@ -9808,6 +9842,7 @@
+
@@ -10238,6 +10273,7 @@
+
@@ -11138,6 +11174,8 @@
+
+
@@ -11328,6 +11366,7 @@
+
@@ -11429,6 +11468,7 @@
+
@@ -11857,6 +11897,7 @@
+
@@ -12051,6 +12092,7 @@
+
@@ -12108,6 +12150,8 @@
+
+
From ae9d0d037c8b2e452aff60ba9185b2e551e68838 Mon Sep 17 00:00:00 2001
From: Gleb <60105060+x9136@users.noreply.github.com>
Date: Mon, 9 Sep 2024 01:32:50 +0300
Subject: [PATCH 110/144] +14 links (#2313)
---
app/assets/appfilter.xml | 14 ++++++++++++++
svgs/castro.svg | 2 +-
svgs/lawnchair.svg | 2 +-
svgs/pi_network.svg | 2 +-
svgs/superimage.svg | 2 +-
5 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index 27867659cda..5185b285a08 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -172,6 +172,7 @@
+
@@ -194,6 +195,7 @@
+
@@ -603,6 +605,7 @@
+
@@ -2617,6 +2620,7 @@
+
@@ -4355,6 +4359,7 @@
+
@@ -4713,6 +4718,7 @@
+
@@ -5656,6 +5662,10 @@
+
+
+
+
@@ -7390,6 +7400,7 @@
+
@@ -7414,6 +7425,7 @@
+
@@ -7837,6 +7849,7 @@
+
@@ -11366,6 +11379,7 @@
+
diff --git a/svgs/castro.svg b/svgs/castro.svg
index 7b226b18acd..179fe77c760 100644
--- a/svgs/castro.svg
+++ b/svgs/castro.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/lawnchair.svg b/svgs/lawnchair.svg
index 0a6c5487e74..ec900f5f3cf 100644
--- a/svgs/lawnchair.svg
+++ b/svgs/lawnchair.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/pi_network.svg b/svgs/pi_network.svg
index 92a24c36dc9..c5d1e33049b 100644
--- a/svgs/pi_network.svg
+++ b/svgs/pi_network.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/svgs/superimage.svg b/svgs/superimage.svg
index e227f5cf92a..2a7f6b6fea0 100644
--- a/svgs/superimage.svg
+++ b/svgs/superimage.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
From ca2473ad47d743dcb2cd650e774709db61339215 Mon Sep 17 00:00:00 2001
From: Pun Butrach
Date: Mon, 9 Sep 2024 21:10:31 +0700
Subject: [PATCH 111/144] Link Lawnchair Google Play Store package name (#2316)
* Link Lawnchair Google Play Store package name
* github is dumb
---
app/assets/appfilter.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/assets/appfilter.xml b/app/assets/appfilter.xml
index 5185b285a08..087ba214fb5 100644
--- a/app/assets/appfilter.xml
+++ b/app/assets/appfilter.xml
@@ -5189,6 +5189,7 @@
+
From 1ce102e5706d110e4f910c848b7d403b762215be Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Mon, 9 Sep 2024 20:43:14 +0800
Subject: [PATCH 112/144] Implement new icons UI
---
app/src/main/AndroidManifest.xml | 4 +-
.../lawnicons/di/NewIconsRepositoryModule.kt | 34 ++++
.../repository/NewIconsRepository.kt | 61 ++++++++
.../lawnicons/repository/PreferenceManager.kt | 93 ++++++++++-
.../app/lawnchair/lawnicons/ui/Lawnicons.kt | 9 +-
.../lawnicons/ui/components/core/Card.kt | 23 ++-
.../ui/components/core/LawniconsScaffold.kt | 6 +-
.../ui/components/home/IconPreviewGrid.kt | 147 +++++++++++-------
.../ui/components/home/NewIconsCard.kt | 112 +++++++++++++
.../ui/components/home/search/SearchBar.kt | 16 +-
.../lawnicons/ui/destination/Home.kt | 89 +++++------
.../lawnicons/ui/destination/NewIcons.kt | 77 +++++++++
.../lawnchair/lawnicons/util/GetIconInfo.kt | 6 +-
.../lawnicons/viewmodel/LawniconsViewModel.kt | 73 +++++++--
.../lawnicons/viewmodel/NewIconsViewModel.kt | 31 ++++
app/src/main/res/drawable/new_releases.xml | 21 +++
app/src/main/res/values/strings.xml | 3 +
.../lawnicons/helper/AppfilterDiffCreator.kt | 81 ++++++++++
.../lawnchair/lawnicons/helper/Application.kt | 21 ++-
.../lawnicons/helper/ConfigProcessor.kt | 19 +++
.../lawnicons/helper/SvgFilesProcessor.kt | 16 ++
.../app/lawnchair/lawnicons/helper/XmlUtil.kt | 16 ++
22 files changed, 801 insertions(+), 157 deletions(-)
create mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/di/NewIconsRepositoryModule.kt
create mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/repository/NewIconsRepository.kt
create mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/NewIconsCard.kt
create mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/NewIcons.kt
create mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/NewIconsViewModel.kt
create mode 100644 app/src/main/res/drawable/new_releases.xml
create mode 100644 svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/AppfilterDiffCreator.kt
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b32bcae0c12..b40f1576d1f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -18,12 +18,12 @@
-
+
-
+
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/di/NewIconsRepositoryModule.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/di/NewIconsRepositoryModule.kt
new file mode 100644
index 00000000000..cef43aedc7a
--- /dev/null
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/di/NewIconsRepositoryModule.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package app.lawnchair.lawnicons.di
+
+import android.app.Application
+import app.lawnchair.lawnicons.repository.NewIconsRepository
+import app.lawnchair.lawnicons.repository.NewIconsRepositoryImpl
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import javax.inject.Singleton
+
+@Module
+@InstallIn(SingletonComponent::class)
+object NewIconsRepositoryModule {
+ @Provides
+ @Singleton
+ fun provideNewIconsRepository(application: Application): NewIconsRepository = NewIconsRepositoryImpl(application)
+}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/NewIconsRepository.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/NewIconsRepository.kt
new file mode 100644
index 00000000000..1866e8621b3
--- /dev/null
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/NewIconsRepository.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package app.lawnchair.lawnicons.repository
+
+import android.app.Application
+import app.lawnchair.lawnicons.BuildConfig
+import app.lawnchair.lawnicons.R
+import app.lawnchair.lawnicons.model.IconInfoModel
+import app.lawnchair.lawnicons.util.getIconInfo
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.launch
+
+interface NewIconsRepository {
+ val newIconsInfoModel: StateFlow
+}
+
+class NewIconsRepositoryImpl @Inject constructor(application: Application) : NewIconsRepository {
+
+ private val coroutineScope = CoroutineScope(Dispatchers.IO)
+ private val prefs = PreferenceManager.getInstance(application)
+
+ private val _newIconsInfoModel = MutableStateFlow(IconInfoModel())
+ override val newIconsInfoModel = _newIconsInfoModel.asStateFlow()
+
+ init {
+ val currentVersionCode = prefs.currentLawniconsVersion.get()
+ val newVersionCode = BuildConfig.VERSION_CODE
+
+ if (currentVersionCode != newVersionCode) {
+ prefs.currentLawniconsVersion.set(newVersionCode)
+ prefs.showNewIconsCard.set(true)
+ }
+
+ coroutineScope.launch {
+ val iconInfo = application.getIconInfo(R.xml.appfilter_diff).sortedBy { it.label.lowercase() }
+ _newIconsInfoModel.value = IconInfoModel(
+ iconInfo,
+ iconInfo.size,
+ )
+ }
+ }
+}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
index b641936f866..75773b25ff5 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
@@ -6,6 +6,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.produceState
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalInspectionMode
+import app.lawnchair.lawnicons.BuildConfig
/**
* A class that abstracts the functionality of SharedPreferences
@@ -45,22 +47,55 @@ abstract class BasePreferenceManager(
}
}
}
+
+ /**
+ * A class that represents a integer preference
+ * @param key The key of the preference
+ * @param defaultValue The default value of the preference
+ */
+ inner class IntPref(
+ val key: String,
+ private val defaultValue: Int,
+ ) {
+ fun get() = prefs.getInt(key, defaultValue)
+ fun set(value: Int) = editor.putInt(key, value).apply()
+
+ @Composable
+ fun asState(): State {
+ return produceState(initialValue = get(), this) {
+ val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, changedKey ->
+ if (changedKey == key) {
+ value = get() // Update the state value when the preference changes
+ }
+ }
+ prefs.registerOnSharedPreferenceChangeListener(listener)
+ awaitDispose {
+ prefs.unregisterOnSharedPreferenceChangeListener(listener)
+ }
+ }
+ }
+ }
}
/**
* Provides a class to handle Lawnicons preferences
+ *
+ * Use [PreferenceManager.getInstance] to get the instance for use thoughout the app.
+ * @see preferenceManager
*/
class PreferenceManager private constructor(
prefs: SharedPreferences,
) : BasePreferenceManager(prefs) {
val showFirstLaunchSnackbar = BoolPref("show_first_launch_snackbar", true)
+ val showNewIconsCard = BoolPref("show_new_icons_card", true)
+ val currentLawniconsVersion = IntPref("current_lawnicons_version", BuildConfig.VERSION_CODE)
companion object {
@Volatile
private var instance: PreferenceManager? = null
/**
- * Returns a singleton instance of PreferenceManager
+ * Returns a singleton instance of [PreferenceManager]
*/
fun getInstance(context: Context): PreferenceManager {
return instance ?: synchronized(this) {
@@ -69,8 +104,62 @@ class PreferenceManager private constructor(
).also { instance = it }
}
}
+
+ /**
+ * Get dummy instance of [PreferenceManager] for testing and Compose previews
+ */
+ fun getDummyInstance(): PreferenceManager {
+ return PreferenceManager(DummySharedPreferences())
+ }
}
}
+/**
+ * Returns a singleton instance of [PreferenceManager] for use in Composable UIs.
+ *
+ * In [LocalInspectionMode], the dummy instance is returned instead.
+ *
+ * @param context the context to use for getting the shared preferences
+ * @return a singleton instance of [PreferenceManager]
+ */
@Composable
-fun preferenceManager(context: Context = LocalContext.current) = PreferenceManager.getInstance(context)
+fun preferenceManager(context: Context = LocalContext.current) = if (LocalInspectionMode.current) {
+ PreferenceManager.getDummyInstance()
+} else {
+ PreferenceManager.getInstance(context)
+}
+
+/**
+ * Dummy implementation of [SharedPreferences] for Compose previews, with mock default values
+ */
+class DummySharedPreferences : SharedPreferences {
+ override fun getAll() = mutableMapOf>()
+ override fun getBoolean(key: String?, defValue: Boolean) = true
+ override fun getString(key: String?, defValue: String?) = ""
+ override fun getStringSet(key: String?, defValues: MutableSet?) = mutableSetOf()
+ override fun getLong(key: String?, defValue: Long) = 0L
+ override fun getFloat(key: String?, defValue: Float) = 0.0f
+ override fun getInt(key: String?, defValue: Int) = 0
+ override fun contains(key: String?) = true
+ override fun edit() = DummyEditor()
+ override fun registerOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener?) {}
+ override fun unregisterOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener?) {}
+
+ /**
+ * Dummy implementation of [SharedPreferences.Editor] for Compose previews
+ */
+ class DummyEditor() : SharedPreferences.Editor {
+ override fun putString(key: String?, value: String?) = DummyEditor()
+ override fun putStringSet(key: String?, values: MutableSet?) = DummyEditor()
+
+ override fun putInt(key: String?, value: Int) = DummyEditor()
+ override fun putLong(key: String?, value: Long) = DummyEditor()
+ override fun putFloat(key: String?, value: Float) = DummyEditor()
+ override fun putBoolean(key: String?, value: Boolean) = DummyEditor()
+ override fun remove(key: String?) = DummyEditor()
+ override fun clear() = DummyEditor()
+
+ override fun commit() = true
+ override fun apply() {}
+ }
+}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt
index 5562654a521..5ffd551ae9a 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/Lawnicons.kt
@@ -16,11 +16,13 @@ import app.lawnchair.lawnicons.ui.destination.Acknowledgement
import app.lawnchair.lawnicons.ui.destination.Acknowledgements
import app.lawnchair.lawnicons.ui.destination.Contributors
import app.lawnchair.lawnicons.ui.destination.Home
+import app.lawnchair.lawnicons.ui.destination.NewIcons
import app.lawnchair.lawnicons.ui.destination.aboutDestination
import app.lawnchair.lawnicons.ui.destination.acknowledgementDestination
import app.lawnchair.lawnicons.ui.destination.acknowledgementsDestination
import app.lawnchair.lawnicons.ui.destination.contributorsDestination
import app.lawnchair.lawnicons.ui.destination.homeDestination
+import app.lawnchair.lawnicons.ui.destination.newIconsDestination
import soup.compose.material.motion.animation.materialSharedAxisXIn
import soup.compose.material.motion.animation.materialSharedAxisXOut
import soup.compose.material.motion.animation.rememberSlideDistance
@@ -49,7 +51,8 @@ fun Lawnicons(
popExitTransition = { materialSharedAxisXOut(isRtl, slideDistance) },
) {
homeDestination(
- onNavigate = { navController.navigate(About) },
+ onNavigateToAbout = { navController.navigate(About) },
+ onNavigateToNewIcons = { navController.navigate(NewIcons) },
isExpandedScreen = isExpandedScreen,
isIconPicker = isIconPicker,
onSendResult = onSendResult,
@@ -79,6 +82,10 @@ fun Lawnicons(
onBack = navController::popBackStack,
isExpandedScreen = isExpandedScreen,
)
+ newIconsDestination(
+ onBack = navController::popBackStack,
+ isExpandedScreen = isExpandedScreen,
+ )
}
}
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/core/Card.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/core/Card.kt
index 94855617e6b..41421916eb9 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/core/Card.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/core/Card.kt
@@ -1,6 +1,7 @@
package app.lawnchair.lawnicons.ui.components.core
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -16,22 +17,18 @@ import app.lawnchair.lawnicons.ui.util.PreviewLawnicons
@Composable
fun Card(
modifier: Modifier = Modifier,
+ contentModifier: Modifier = Modifier,
label: String? = null,
- content: @Composable () -> Unit,
+ content: @Composable ColumnScope.() -> Unit,
) {
Column(modifier = modifier) {
if (label != null) {
- Text(
- text = label,
- style = MaterialTheme.typography.titleSmall,
- color = MaterialTheme.colorScheme.primary,
- modifier = Modifier.padding(start = 32.dp, bottom = 6.dp),
- )
+ CardHeader(label)
}
Surface(
color = MaterialTheme.colorScheme.surfaceContainer,
shape = RoundedCornerShape(size = 16.dp),
- modifier = Modifier
+ modifier = contentModifier
.padding(horizontal = 16.dp)
.fillMaxWidth(),
) {
@@ -42,6 +39,16 @@ fun Card(
}
}
+@Composable
+fun CardHeader(label: String, modifier: Modifier = Modifier) {
+ Text(
+ text = label,
+ style = MaterialTheme.typography.titleSmall,
+ color = MaterialTheme.colorScheme.primary,
+ modifier = modifier.padding(start = 32.dp, bottom = 6.dp),
+ )
+}
+
@PreviewLawnicons
@Composable
private fun CardPreview() {
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/core/LawniconsScaffold.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/core/LawniconsScaffold.kt
index fef3a4c2e6e..4bd3d20a073 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/core/LawniconsScaffold.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/core/LawniconsScaffold.kt
@@ -29,10 +29,8 @@ fun LawniconsScaffold(
modifier: Modifier = Modifier,
content: @Composable (PaddingValues) -> Unit,
) {
- var scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
- if (isExpandedScreen) {
- scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
- }
+ val scrollBehavior =
+ if (isExpandedScreen) TopAppBarDefaults.pinnedScrollBehavior() else TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
index 3821e3e60fb..8e0dd7864be 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
@@ -10,7 +10,6 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
@@ -25,6 +24,7 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
+import androidx.compose.foundation.lazy.grid.LazyGridItemScope
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
@@ -49,6 +49,7 @@ import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import app.lawnchair.lawnicons.R
import app.lawnchair.lawnicons.model.IconInfo
@@ -61,16 +62,39 @@ import my.nanihadesuka.compose.InternalLazyVerticalGridScrollbar
import my.nanihadesuka.compose.ScrollbarSelectionMode
import my.nanihadesuka.compose.ScrollbarSettings
+data class IconPreviewGridPadding(
+ val topPadding: Dp,
+ val bottomPadding: Dp,
+ val horizontalPadding: Dp,
+) {
+
+ companion object {
+ val Defaults = IconPreviewGridPadding(
+ topPadding = 0.dp,
+ bottomPadding = 80.dp,
+ horizontalPadding = 8.dp,
+ )
+
+ val ExpandedSize = IconPreviewGridPadding(
+ topPadding = 72.dp,
+ bottomPadding = 0.dp,
+ horizontalPadding = 32.dp,
+ )
+ }
+}
+
@Composable
@ExperimentalFoundationApi
fun IconPreviewGrid(
iconInfo: List,
- isExpandedScreen: Boolean,
onSendResult: (IconInfo) -> Unit,
modifier: Modifier = Modifier,
+ containerModifier: Modifier = Modifier
+ .applyGridInsets(),
+ contentPadding: IconPreviewGridPadding = IconPreviewGridPadding.Defaults,
isIconPicker: Boolean = false,
- contentPadding: PaddingValues? = null,
gridState: LazyGridState = rememberLazyGridState(),
+ otherContent: @Composable (LazyGridItemScope.() -> Unit) = {},
) {
val indexOfFirstItem by remember { derivedStateOf { gridState.firstVisibleItemIndex } }
val letter = iconInfo[indexOfFirstItem].label[0].uppercase()
@@ -81,48 +105,30 @@ fun IconPreviewGrid(
verticalArrangement = Arrangement.Center,
modifier = modifier.fillMaxWidth(),
) {
- val horizontalGridPadding = if (isExpandedScreen) 32.dp else 8.dp
Box(
- modifier = Modifier
- .widthIn(max = 640.dp)
- .fillMaxWidth()
- .statusBarsPadding()
- .then(
- if (isExpandedScreen) {
- Modifier.padding(top = 26.dp)
- } else {
- Modifier.padding(
- bottom = 80.dp,
- )
- },
- ),
+ modifier = containerModifier
+ .padding(bottom = contentPadding.bottomPadding),
) {
LazyVerticalGrid(
columns = GridCells.Adaptive(minSize = 80.dp),
- contentPadding = contentPadding ?: WindowInsets.navigationBars.toPaddingValues(
- additionalStart = horizontalGridPadding,
- additionalTop = if (isExpandedScreen) 42.dp else 0.dp,
- additionalEnd = horizontalGridPadding,
+ contentPadding = WindowInsets.navigationBars.toPaddingValues(
+ additionalStart = contentPadding.horizontalPadding,
+ additionalTop = contentPadding.topPadding,
+ additionalEnd = contentPadding.horizontalPadding,
),
state = gridState,
) {
- if (!isExpandedScreen) {
- item(
- span = {
- GridItemSpan(maxLineSpan)
- },
- ) {
- AppBarListItem()
- }
+ item(
+ span = { GridItemSpan(maxLineSpan) },
+ ) {
+ otherContent()
}
items(
items = iconInfo,
contentType = { "icon_preview" },
) { iconInfo ->
val scale by animateFloatAsState(
- if (thumbSelected && iconInfo.label.first()
- .toString() == letter
- ) {
+ if (thumbSelected && iconInfo.label.first().toString() == letter) {
1.1f
} else {
1f
@@ -138,35 +144,56 @@ fun IconPreviewGrid(
)
}
}
- Box(
- contentAlignment = Alignment.CenterEnd,
- ) {
- Spacer(
- Modifier
- .fillMaxHeight()
- .width(8.dp)
- .background(MaterialTheme.colorScheme.surfaceContainer)
- .clip(CircleShape),
- )
- InternalLazyVerticalGridScrollbar(
- modifier = Modifier.offset(7.dp),
- state = gridState,
- settings = ScrollbarSettings(
- alwaysShowScrollbar = true,
- thumbUnselectedColor = MaterialTheme.colorScheme.primary,
- thumbSelectedColor = MaterialTheme.colorScheme.primary,
- selectionMode = ScrollbarSelectionMode.Thumb,
- ),
- indicatorContent = { _, isThumbSelected ->
- thumbSelected = isThumbSelected
- ScrollbarIndicator(letter, isThumbSelected)
- },
- )
- }
+ ScrollbarLayout(
+ gridState,
+ { thumbSelected = it },
+ letter,
+ contentPadding.topPadding,
+ )
}
}
}
+private fun Modifier.applyGridInsets() = this
+ .widthIn(max = 640.dp)
+ .fillMaxWidth()
+ .statusBarsPadding()
+
+@Composable
+private fun ScrollbarLayout(
+ gridState: LazyGridState,
+ onSelectedChange: (Boolean) -> Unit,
+ currentLetter: String,
+ topPadding: Dp = 0.dp,
+) {
+ Box(
+ contentAlignment = Alignment.CenterEnd,
+ modifier = Modifier.padding(top = topPadding),
+ ) {
+ Spacer(
+ Modifier
+ .fillMaxHeight()
+ .width(8.dp)
+ .background(MaterialTheme.colorScheme.surfaceContainer)
+ .clip(CircleShape),
+ )
+ InternalLazyVerticalGridScrollbar(
+ modifier = Modifier.offset(7.dp),
+ state = gridState,
+ settings = ScrollbarSettings(
+ alwaysShowScrollbar = true,
+ thumbUnselectedColor = MaterialTheme.colorScheme.primary,
+ thumbSelectedColor = MaterialTheme.colorScheme.primary,
+ selectionMode = ScrollbarSelectionMode.Thumb,
+ ),
+ indicatorContent = { _, isThumbSelected ->
+ onSelectedChange(isThumbSelected)
+ ScrollbarIndicator(currentLetter, isThumbSelected)
+ },
+ )
+ }
+}
+
@Composable
private fun ScrollbarIndicator(
label: String,
@@ -197,7 +224,7 @@ private fun ScrollbarIndicator(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
-private fun AppBarListItem(modifier: Modifier = Modifier) {
+fun AppBarListItem(modifier: Modifier = Modifier) {
val context = LocalContext.current
CenterAlignedTopAppBar(
modifier = modifier,
@@ -229,9 +256,9 @@ private fun IconGridPreview() {
Surface {
IconPreviewGrid(
iconInfo = SampleData.iconInfoList,
- isExpandedScreen = false,
onSendResult = {},
modifier = Modifier,
+ contentPadding = IconPreviewGridPadding.Defaults,
isIconPicker = false,
)
}
@@ -246,9 +273,9 @@ private fun IconGridExpandedPreview() {
Surface {
IconPreviewGrid(
iconInfo = SampleData.iconInfoList,
- isExpandedScreen = true,
onSendResult = {},
modifier = Modifier,
+ contentPadding = IconPreviewGridPadding.ExpandedSize,
isIconPicker = false,
)
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/NewIconsCard.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/NewIconsCard.kt
new file mode 100644
index 00000000000..adef79bb553
--- /dev/null
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/NewIconsCard.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package app.lawnchair.lawnicons.ui.components.home
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.rounded.Clear
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import app.lawnchair.lawnicons.BuildConfig
+import app.lawnchair.lawnicons.R
+import app.lawnchair.lawnicons.repository.preferenceManager
+import app.lawnchair.lawnicons.ui.components.core.Card
+import app.lawnchair.lawnicons.ui.theme.LawniconsTheme
+import app.lawnchair.lawnicons.ui.util.PreviewLawnicons
+
+@Composable
+fun NewIconsCard(
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ val prefs = preferenceManager()
+ val cardState = prefs.showNewIconsCard.asState()
+ NewIconsCard(
+ onClick = onClick,
+ visible = cardState.value,
+ onVisibilityChange = {
+ prefs.showNewIconsCard.set(false)
+ },
+ modifier = modifier,
+ )
+}
+
+@Composable
+fun NewIconsCard(
+ onClick: () -> Unit,
+ visible: Boolean,
+ onVisibilityChange: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ AnimatedVisibility(visible) {
+ Card(
+ modifier = modifier,
+ ) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .clickable { onClick() }
+ .padding(start = 12.dp),
+ ) {
+ Row {
+ Icon(
+ painterResource(R.drawable.new_releases),
+ contentDescription = null,
+ )
+ Spacer(Modifier.width(8.dp))
+ Text(
+ text = stringResource(
+ R.string.new_icons_in_version,
+ BuildConfig.VERSION_NAME,
+ ),
+ style = MaterialTheme.typography.titleSmall,
+ )
+ }
+ Spacer(Modifier.weight(1f))
+ IconButton(
+ onClick = onVisibilityChange,
+ ) {
+ Icon(Icons.Rounded.Clear, contentDescription = stringResource(R.string.clear))
+ }
+ }
+ }
+ }
+}
+
+@PreviewLawnicons
+@Composable
+private fun NewIconsCardPreview() {
+ LawniconsTheme {
+ Surface {
+ NewIconsCard({})
+ }
+ }
+}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchBar.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchBar.kt
index c2e1d4ac3d5..00bf7162860 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchBar.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/search/SearchBar.kt
@@ -261,15 +261,13 @@ internal fun SearchIcon(
active: Boolean,
onButtonClick: () -> Unit,
) {
- Crossfade(active, label = "") {
- if (it) {
- ClickableIcon(
- imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
- onClick = onButtonClick,
- )
- } else {
- Icon(Icons.Rounded.Search, contentDescription = null)
- }
+ if (active) {
+ ClickableIcon(
+ imageVector = Icons.AutoMirrored.Rounded.ArrowBack,
+ onClick = onButtonClick,
+ )
+ } else {
+ Icon(Icons.Rounded.Search, contentDescription = null)
}
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
index a257463e19f..52ada0381f2 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
@@ -8,16 +8,14 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.material3.CircularProgressIndicator
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
+import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
@@ -27,19 +25,20 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import app.lawnchair.lawnicons.model.IconInfo
-import app.lawnchair.lawnicons.model.SearchMode
+import app.lawnchair.lawnicons.ui.components.home.AppBarListItem
import app.lawnchair.lawnicons.ui.components.home.HomeBottomBar
import app.lawnchair.lawnicons.ui.components.home.HomeTopBar
import app.lawnchair.lawnicons.ui.components.home.HomeTopBarUiState
import app.lawnchair.lawnicons.ui.components.home.IconPreviewGrid
+import app.lawnchair.lawnicons.ui.components.home.IconPreviewGridPadding
import app.lawnchair.lawnicons.ui.components.home.IconRequestFAB
-import app.lawnchair.lawnicons.ui.components.home.search.LawniconsSearchBar
+import app.lawnchair.lawnicons.ui.components.home.NewIconsCard
import app.lawnchair.lawnicons.ui.components.home.search.PlaceholderSearchBar
-import app.lawnchair.lawnicons.ui.components.home.search.SearchContents
import app.lawnchair.lawnicons.ui.theme.LawniconsTheme
import app.lawnchair.lawnicons.ui.util.PreviewLawnicons
-import app.lawnchair.lawnicons.ui.util.SampleData
+import app.lawnchair.lawnicons.viewmodel.DummyLawniconsViewModel
import app.lawnchair.lawnicons.viewmodel.LawniconsViewModel
+import app.lawnchair.lawnicons.viewmodel.LawniconsViewModelImpl
import kotlinx.serialization.Serializable
@Serializable
@@ -48,12 +47,14 @@ data object Home
fun NavGraphBuilder.homeDestination(
isExpandedScreen: Boolean,
isIconPicker: Boolean,
- onNavigate: () -> Unit,
+ onNavigateToAbout: () -> Unit,
+ onNavigateToNewIcons: () -> Unit,
onSendResult: (IconInfo) -> Unit,
) {
composable {
Home(
- onNavigate = onNavigate,
+ onNavigateToAbout = onNavigateToAbout,
+ onNavigateToNewIcons = onNavigateToNewIcons,
isExpandedScreen = isExpandedScreen,
isIconPicker = isIconPicker,
onSendResult = onSendResult,
@@ -62,20 +63,22 @@ fun NavGraphBuilder.homeDestination(
}
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
-@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun Home(
- onNavigate: () -> Unit,
+ onNavigateToAbout: () -> Unit,
+ onNavigateToNewIcons: () -> Unit,
onSendResult: (IconInfo) -> Unit,
isExpandedScreen: Boolean,
modifier: Modifier = Modifier,
isIconPicker: Boolean = false,
- lawniconsViewModel: LawniconsViewModel = hiltViewModel(),
+ lawniconsViewModel: LawniconsViewModel = hiltViewModel(),
) {
with(lawniconsViewModel) {
val iconInfoModel by iconInfoModel.collectAsStateWithLifecycle()
val searchedIconInfoModel by searchedIconInfoModel.collectAsStateWithLifecycle()
val iconRequestModel by iconRequestModel.collectAsStateWithLifecycle()
+ val newIconsInfoModel by newIconsInfoModel.collectAsStateWithLifecycle()
val context = LocalContext.current
val lazyGridState = rememberLazyGridState()
@@ -104,7 +107,7 @@ private fun Home(
onClearSearch = ::clearSearch,
onChangeMode = ::changeMode,
onSearchIcons = ::searchIcons,
- onNavigate = onNavigate,
+ onNavigate = onNavigateToAbout,
onSendResult = onSendResult,
focusRequester = focusRequester,
)
@@ -115,7 +118,7 @@ private fun Home(
context = context,
iconRequestModel = iconRequestModel,
snackbarHostState = snackbarHostState,
- onNavigate = onNavigate,
+ onNavigate = onNavigateToAbout,
onExpandSearch = { expandSearch = true },
)
}
@@ -135,11 +138,20 @@ private fun Home(
) {
IconPreviewGrid(
iconInfo = iconInfoModel.iconInfo,
- isExpandedScreen = isExpandedScreen,
- isIconPicker = isIconPicker,
onSendResult = onSendResult,
+ contentPadding = if (isExpandedScreen) IconPreviewGridPadding.ExpandedSize else IconPreviewGridPadding.Defaults,
+ isIconPicker = isIconPicker,
gridState = lazyGridState,
- )
+ ) {
+ Column {
+ if (!isExpandedScreen) {
+ AppBarListItem()
+ }
+ if (newIconsInfoModel.iconCount != 0) {
+ NewIconsCard(onNavigateToNewIcons)
+ }
+ }
+ }
}
} else {
if (isExpandedScreen) {
@@ -163,43 +175,18 @@ private fun Home(
}
}
-@OptIn(ExperimentalFoundationApi::class)
@PreviewLawnicons
@Composable
private fun HomePreview() {
- var searchTerm by remember { mutableStateOf(value = "") }
- val iconInfo = SampleData.iconInfoList
-
LawniconsTheme {
- LawniconsSearchBar(
- query = searchTerm,
- isQueryEmpty = searchTerm == "",
- onClear = {
- searchTerm = ""
- },
- onBack = {},
- onQueryChange = { newValue ->
- searchTerm = newValue
- // No actual searching, this is just a preview
- },
- iconCount = 3,
- onNavigate = {},
- isExpandedScreen = true,
- content = {
- SearchContents(
- "",
- SearchMode.LABEL,
- {},
- iconInfo = iconInfo,
- )
- },
- )
- IconPreviewGrid(
- iconInfo = iconInfo,
- isExpandedScreen = false,
- {},
- Modifier,
- false,
- )
+ Surface(Modifier.fillMaxSize()) {
+ Home(
+ onNavigateToAbout = {},
+ onNavigateToNewIcons = {},
+ isExpandedScreen = true,
+ onSendResult = {},
+ lawniconsViewModel = DummyLawniconsViewModel(),
+ )
+ }
}
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/NewIcons.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/NewIcons.kt
new file mode 100644
index 00000000000..50ecbed8c97
--- /dev/null
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/NewIcons.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package app.lawnchair.lawnicons.ui.destination
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
+import app.lawnchair.lawnicons.R
+import app.lawnchair.lawnicons.ui.components.core.LawniconsScaffold
+import app.lawnchair.lawnicons.ui.components.home.IconPreviewGrid
+import app.lawnchair.lawnicons.ui.components.home.IconPreviewGridPadding
+import app.lawnchair.lawnicons.viewmodel.NewIconsViewModel
+import kotlinx.serialization.Serializable
+
+@Serializable
+data object NewIcons
+
+fun NavGraphBuilder.newIconsDestination(
+ isExpandedScreen: Boolean,
+ onBack: () -> Unit,
+) {
+ composable {
+ NewIcons(
+ onBack = onBack,
+ isExpandedScreen = isExpandedScreen,
+ )
+ }
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+@Composable
+private fun NewIcons(
+ onBack: () -> Unit,
+ isExpandedScreen: Boolean,
+ modifier: Modifier = Modifier,
+ newIconsViewModel: NewIconsViewModel = hiltViewModel(),
+) {
+ val iconInfoModel by newIconsViewModel.newIconsInfoModel.collectAsStateWithLifecycle()
+
+ LawniconsScaffold(
+ modifier = modifier,
+ title = stringResource(R.string.new_icons, iconInfoModel.iconCount),
+ onBack = onBack,
+ isExpandedScreen = isExpandedScreen,
+ ) { paddingValues ->
+ IconPreviewGrid(
+ iconInfo = iconInfoModel.iconInfo,
+ onSendResult = {},
+ contentPadding = IconPreviewGridPadding(
+ topPadding = paddingValues.calculateTopPadding() - 24.dp,
+ bottomPadding = paddingValues.calculateBottomPadding(),
+ horizontalPadding = if (isExpandedScreen) IconPreviewGridPadding.ExpandedSize.horizontalPadding else IconPreviewGridPadding.Defaults.horizontalPadding,
+ ),
+ )
+ }
+}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/util/GetIconInfo.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/util/GetIconInfo.kt
index 7ea59aeb188..d162a0a68e6 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/util/GetIconInfo.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/util/GetIconInfo.kt
@@ -2,6 +2,7 @@ package app.lawnchair.lawnicons.util
import android.annotation.SuppressLint
import android.content.Context
+import androidx.annotation.XmlRes
import app.lawnchair.lawnicons.R
import app.lawnchair.lawnicons.model.IconInfo
import app.lawnchair.lawnicons.model.LabelAndComponent
@@ -9,13 +10,14 @@ import app.lawnchair.lawnicons.model.mergeByDrawableName
import org.xmlpull.v1.XmlPullParser
@SuppressLint("DiscouragedApi")
-fun Context.getIconInfo(): List {
+fun Context.getIconInfo(
+ @XmlRes xmlId: Int = R.xml.appfilter,
+): List {
val iconInfo = mutableListOf()
val componentInfoPrefixLength = "ComponentInfo{".length
try {
- val xmlId = R.xml.appfilter
if (xmlId != 0) {
val parser = resources.getXml(xmlId)
val depth = parser.depth
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt
index b6d23e9fefc..c5510c80bdb 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/LawniconsViewModel.kt
@@ -5,55 +5,94 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import app.lawnchair.lawnicons.model.IconInfoModel
+import app.lawnchair.lawnicons.model.IconRequestModel
import app.lawnchair.lawnicons.model.SearchMode
import app.lawnchair.lawnicons.repository.IconRepository
+import app.lawnchair.lawnicons.repository.NewIconsRepository
+import app.lawnchair.lawnicons.ui.util.SampleData
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
-@HiltViewModel
-class LawniconsViewModel @Inject constructor(
- private val iconRepository: IconRepository,
-) :
- ViewModel() {
- @JvmField
- val iconInfoModel = iconRepository.iconInfoModel
+interface LawniconsViewModel {
+ val iconInfoModel: StateFlow
+ val searchedIconInfoModel: StateFlow
+ val iconRequestModel: StateFlow
+ val newIconsInfoModel: StateFlow
+
+ var expandSearch: Boolean
+
+ val searchMode: SearchMode
+ val searchTerm: String
- @JvmField
- val searchedIconInfoModel = iconRepository.searchedIconInfoModel
+ fun searchIcons(query: String)
+ fun changeMode(mode: SearchMode)
+ fun clearSearch()
+}
- @JvmField
- val iconRequestModel = iconRepository.iconRequestList
+@HiltViewModel
+class LawniconsViewModelImpl @Inject constructor(
+ private val iconRepository: IconRepository,
+ private val newIconsRepository: NewIconsRepository,
+) : LawniconsViewModel, ViewModel() {
+ override val iconInfoModel = iconRepository.iconInfoModel
+ override val searchedIconInfoModel = iconRepository.searchedIconInfoModel
+ override val iconRequestModel = iconRepository.iconRequestList
+ override val newIconsInfoModel = newIconsRepository.newIconsInfoModel
- var expandSearch by mutableStateOf(false)
+ override var expandSearch by mutableStateOf(false)
private var _searchMode by mutableStateOf(SearchMode.LABEL)
private var _searchTerm by mutableStateOf("")
- val searchMode: SearchMode
+ override val searchMode: SearchMode
get() = _searchMode
- val searchTerm: String
+ override val searchTerm: String
get() = _searchTerm
- fun searchIcons(query: String) {
+ override fun searchIcons(query: String) {
_searchTerm = query
viewModelScope.launch {
iconRepository.search(searchMode, searchTerm)
}
}
- fun changeMode(mode: SearchMode) {
+ override fun changeMode(mode: SearchMode) {
_searchMode = mode
viewModelScope.launch {
iconRepository.search(searchMode, searchTerm)
}
}
- fun clearSearch() {
+ override fun clearSearch() {
_searchTerm = ""
viewModelScope.launch {
iconRepository.clearSearch()
}
}
}
+
+class DummyLawniconsViewModel : LawniconsViewModel {
+ private val list = SampleData.iconInfoList
+
+ override val iconInfoModel = MutableStateFlow(IconInfoModel(iconInfo = list, iconCount = list.size)).asStateFlow()
+ override val searchedIconInfoModel = MutableStateFlow(IconInfoModel(iconInfo = list, iconCount = list.size)).asStateFlow()
+ override val iconRequestModel = MutableStateFlow(IconRequestModel(list = listOf(), iconCount = 0)).asStateFlow()
+ override val newIconsInfoModel = MutableStateFlow(IconInfoModel(iconInfo = list, iconCount = list.size)).asStateFlow()
+
+ override var expandSearch by mutableStateOf(false)
+
+ override val searchMode = SearchMode.LABEL
+ override val searchTerm = ""
+
+ override fun searchIcons(query: String) {}
+
+ override fun changeMode(mode: SearchMode) {}
+
+ override fun clearSearch() {}
+}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/NewIconsViewModel.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/NewIconsViewModel.kt
new file mode 100644
index 00000000000..8b7136527c7
--- /dev/null
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/viewmodel/NewIconsViewModel.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package app.lawnchair.lawnicons.viewmodel
+
+import androidx.lifecycle.ViewModel
+import app.lawnchair.lawnicons.repository.NewIconsRepository
+import dagger.hilt.android.lifecycle.HiltViewModel
+import javax.inject.Inject
+
+@HiltViewModel
+class NewIconsViewModel @Inject constructor(
+ private val newIconsRepository: NewIconsRepository,
+) : ViewModel() {
+
+ @JvmField
+ val newIconsInfoModel = newIconsRepository.newIconsInfoModel
+}
diff --git a/app/src/main/res/drawable/new_releases.xml b/app/src/main/res/drawable/new_releases.xml
new file mode 100644
index 00000000000..9eec8a7b8eb
--- /dev/null
+++ b/app/src/main/res/drawable/new_releases.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3f3ff0e25c4..976cffe6bc0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -86,4 +86,7 @@
Copied icon request details to clipboard. To request them, submit the details into the form.
Open form
+ Clear
+ New icons in v%1$s
+ New icons (%1$s)
diff --git a/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/AppfilterDiffCreator.kt b/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/AppfilterDiffCreator.kt
new file mode 100644
index 00000000000..3988d9319b4
--- /dev/null
+++ b/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/AppfilterDiffCreator.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package app.lawnchair.lawnicons.helper
+
+import java.io.File
+
+object AppfilterDiffCreator {
+ private const val OUTPUT_FILE = "/xml/appfilter_diff.xml"
+
+ private fun getBranchContents(
+ branch: String,
+ appFilterFile: String,
+ ): List {
+ val command = listOf("git", "show", "$branch:$appFilterFile")
+ val process = ProcessBuilder(command)
+ .redirectErrorStream(true)
+ .start()
+
+ val result = process.inputStream.bufferedReader().readLines()
+ if (process.waitFor() != 0) {
+ throw RuntimeException("Failed to execute command: $command")
+ }
+ return result
+ }
+
+ private fun getLineDiff(
+ mainLines: List,
+ developLines: List,
+ ): List {
+ return developLines.filterNot { it in mainLines }
+ }
+
+ private fun writeDiffToFile(
+ diff: List,
+ resDir: String,
+ ) {
+ val outputFile = File(resDir + OUTPUT_FILE)
+ val schema = ""
+
+ if (diff.isEmpty()) {
+ outputFile.writeText("$schema\n")
+ return
+ }
+
+ val xmlContent = buildString {
+ appendLine(schema)
+ appendLine("")
+ diff.forEach { line ->
+ appendLine(" $line")
+ }
+ appendLine("")
+ }
+
+ outputFile.writeText(xmlContent)
+ }
+
+ fun createAppfilterDiff(
+ resDir: String,
+ appFilterFile: String,
+ ) {
+ val mainLines = getBranchContents("main", appFilterFile)
+ val developLines = getBranchContents("develop", appFilterFile)
+ val diff = getLineDiff(mainLines, developLines)
+
+ writeDiffToFile(diff, resDir)
+ }
+}
diff --git a/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/Application.kt b/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/Application.kt
index a016e388349..e97ded9b314 100644
--- a/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/Application.kt
+++ b/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/Application.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
package app.lawnchair.lawnicons.helper
fun main() {
@@ -8,9 +24,12 @@ fun main() {
// Convert svg to drawable in runtime
SvgFilesProcessor.process(sourceDir, "$resDir/drawable")
+ println("SvgToVectorDrawable task completed")
// Read appfilter xml and create icon, drawable xml file.
ConfigProcessor.loadAndCreateConfigs(appFilterFile, resDir)
+ println("ConfigProcessor task completed")
- println("SvgToVector task completed")
+ AppfilterDiffCreator.createAppfilterDiff(resDir, appFilterFile)
+ println("Appfilter diff task completed")
}
diff --git a/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/ConfigProcessor.kt b/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/ConfigProcessor.kt
index 33b16af250e..3bc95143baf 100644
--- a/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/ConfigProcessor.kt
+++ b/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/ConfigProcessor.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
package app.lawnchair.lawnicons.helper
import java.util.Locale
@@ -25,10 +41,13 @@ object ConfigProcessor {
resDirs.forEach {
// Create Drawable files
writeDrawableToFile(sortedDrawableMap, "$it/xml/drawable.xml")
+ println("Written drawables to $it/xml/drawable.xml")
// Create Icon Map files
writeIconMapToFile(sortedDrawableMap, iconMap, "$it/xml/grayscale_icon_map.xml")
+ println("Created grayscale_icon_map.xml")
// Write AppFilter to resource directory
XmlUtil.writeDocumentToFile(appFilterDocument, "$it/xml/appfilter.xml")
+ println("Created appfilter.xml")
}
}
diff --git a/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/SvgFilesProcessor.kt b/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/SvgFilesProcessor.kt
index a0b8c3099f8..93bd91a34ae 100644
--- a/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/SvgFilesProcessor.kt
+++ b/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/SvgFilesProcessor.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
package app.lawnchair.lawnicons.helper
import com.android.ide.common.vectordrawable.Svg2Vector
diff --git a/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/XmlUtil.kt b/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/XmlUtil.kt
index bfe417d87f8..45db04313fb 100644
--- a/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/XmlUtil.kt
+++ b/svg-processor/src/main/kotlin/app/lawnchair/lawnicons/helper/XmlUtil.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
package app.lawnchair.lawnicons.helper
import java.io.File
From 7708507ad6963c900179a70e75363015b3434dee Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Mon, 9 Sep 2024 21:19:28 +0800
Subject: [PATCH 113/144] Improve UX for icon request disabling
---
.../lawnicons/repository/PreferenceManager.kt | 12 +--
.../ui/components/home/IconRequestFAB.kt | 89 +++++++++++--------
2 files changed, 58 insertions(+), 43 deletions(-)
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
index 75773b25ff5..50e03618da7 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
@@ -77,12 +77,6 @@ abstract class BasePreferenceManager(
}
}
-/**
- * Provides a class to handle Lawnicons preferences
- *
- * Use [PreferenceManager.getInstance] to get the instance for use thoughout the app.
- * @see preferenceManager
- */
class PreferenceManager private constructor(
prefs: SharedPreferences,
) : BasePreferenceManager(prefs) {
@@ -90,6 +84,12 @@ class PreferenceManager private constructor(
val showNewIconsCard = BoolPref("show_new_icons_card", true)
val currentLawniconsVersion = IntPref("current_lawnicons_version", BuildConfig.VERSION_CODE)
+ /**
+ * Provides a class to handle Lawnicons preferences.
+ *
+ * Use [PreferenceManager.getInstance] to get the instance for use thoughout the app.
+ * @see preferenceManager
+ */
companion object {
@Volatile
private var instance: PreferenceManager? = null
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
index 53dfd79868d..83ce44a0e6d 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
@@ -20,8 +20,10 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
+import androidx.compose.material3.FloatingActionButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.SheetState
import androidx.compose.material3.SnackbarDuration
@@ -68,7 +70,10 @@ fun IconRequestFAB(
modifier: Modifier = Modifier,
) {
val list = iconRequestModel?.list ?: emptyList()
+ val enabled = iconRequestModel != null
+
RequestHandler(
+ enabled = enabled,
iconRequestList = list,
snackbarHostState = snackbarHostState,
) { interactionSource ->
@@ -84,7 +89,8 @@ fun IconRequestFAB(
},
onClick = {},
expanded = lazyGridState.isScrollingUp(),
- interactionSource = interactionSource,
+ interactionSource = if (enabled) interactionSource else null,
+ containerColor = if (!enabled) MaterialTheme.colorScheme.surfaceVariant else FloatingActionButtonDefaults.containerColor,
modifier = modifier,
)
}
@@ -97,14 +103,17 @@ fun IconRequestIconButton(
modifier: Modifier = Modifier,
) {
val list = iconRequestModel?.list ?: emptyList()
+ val enabled = iconRequestModel != null
RequestHandler(
+ enabled = enabled,
iconRequestList = list,
snackbarHostState = snackbarHostState,
) { interactionSource ->
IconButton(
onClick = {},
- interactionSource = interactionSource,
+ enabled = enabled,
+ interactionSource = if (enabled) interactionSource else null,
modifier = modifier,
) {
Icon(
@@ -119,6 +128,7 @@ fun IconRequestIconButton(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun RequestHandler(
+ enabled: Boolean,
iconRequestList: List,
snackbarHostState: SnackbarHostState,
content: @Composable ((interactionSource: MutableInteractionSource) -> Unit),
@@ -140,6 +150,7 @@ fun RequestHandler(
val interactionSource = remember { MutableInteractionSource() }
HandleTouchInteractions(
+ enabled = enabled,
interactionSource = interactionSource,
viewConfiguration = LocalViewConfiguration.current,
context = context,
@@ -155,13 +166,15 @@ fun RequestHandler(
content(interactionSource)
- if (showFirstLaunchSnackbar && iconRequestList.isNotEmpty()) {
- openSnackbarFirstLaunchContent(
- context,
- scope,
- prefs.showFirstLaunchSnackbar::toggle,
- snackbarHostState,
- )
+ LaunchedEffect(iconRequestList.isNotEmpty()) {
+ if (showFirstLaunchSnackbar) {
+ openSnackbarFirstLaunchContent(
+ context,
+ scope,
+ { prefs.showFirstLaunchSnackbar.set(false) },
+ snackbarHostState,
+ )
+ }
}
AnimatedVisibility(visible = sheetExpanded) {
@@ -177,6 +190,7 @@ fun RequestHandler(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun HandleTouchInteractions(
+ enabled: Boolean,
interactionSource: MutableInteractionSource,
viewConfiguration: ViewConfiguration,
context: Context,
@@ -189,40 +203,41 @@ private fun HandleTouchInteractions(
encodedRequestList: String,
snackbarHostState: SnackbarHostState,
) {
- val prefs = preferenceManager()
val lastestOnExpandSheet by rememberUpdatedState(newValue = onExpandSheet)
- LaunchedEffect(interactionSource) {
- var isLongClick = false
- interactionSource.interactions.collectLatest { interaction ->
- when (interaction) {
- is PressInteraction.Press -> {
- isLongClick = false
- delay(viewConfiguration.longPressTimeoutMillis)
- isLongClick = true
- coroutineScope.launch {
- lastestOnExpandSheet(true)
- sheetState.show()
+ if (enabled) {
+ LaunchedEffect(interactionSource) {
+ var isLongClick = false
+
+ interactionSource.interactions.collectLatest { interaction ->
+ when (interaction) {
+ is PressInteraction.Press -> {
+ isLongClick = false
+ delay(viewConfiguration.longPressTimeoutMillis)
+ isLongClick = true
+ coroutineScope.launch {
+ lastestOnExpandSheet(true)
+ sheetState.show()
+ }
}
- }
- is PressInteraction.Release -> {
- if (!isLongClick) {
- prefs.showFirstLaunchSnackbar.set(false)
- handleRequestClick(
- iconRequestList,
- context,
- directLinkEnabled,
- encodedRequestList,
- requestList,
- coroutineScope,
- snackbarHostState,
- )
+ is PressInteraction.Release -> {
+ if (!isLongClick) {
+ handleRequestClick(
+ iconRequestList,
+ context,
+ directLinkEnabled,
+ encodedRequestList,
+ requestList,
+ coroutineScope,
+ snackbarHostState,
+ )
+ }
}
- }
- is PressInteraction.Cancel -> {
- isLongClick = false
+ is PressInteraction.Cancel -> {
+ isLongClick = false
+ }
}
}
}
From 26300ccafe491aa65b52430bf6af92a384a4b065 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Mon, 9 Sep 2024 22:23:47 +0800
Subject: [PATCH 114/144] Add debug menu
---
.../lawnicons/repository/PreferenceManager.kt | 1 +
.../lawnicons/ui/components/home/DebugMenu.kt | 172 ++++++++++++++++++
.../ui/components/home/HomeBottomBar.kt | 3 +-
.../ui/components/home/IconPreviewGrid.kt | 14 +-
.../ui/components/home/IconRequestFAB.kt | 142 +++++----------
.../lawnicons/ui/destination/Home.kt | 12 +-
.../lawnchair/lawnicons/ui/util/Clipboard.kt | 28 +++
7 files changed, 268 insertions(+), 104 deletions(-)
create mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/DebugMenu.kt
create mode 100644 app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/Clipboard.kt
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
index 50e03618da7..700a06057cd 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/repository/PreferenceManager.kt
@@ -82,6 +82,7 @@ class PreferenceManager private constructor(
) : BasePreferenceManager(prefs) {
val showFirstLaunchSnackbar = BoolPref("show_first_launch_snackbar", true)
val showNewIconsCard = BoolPref("show_new_icons_card", true)
+ val showDebugMenu = BoolPref("debug_menu", false)
val currentLawniconsVersion = IntPref("current_lawnicons_version", BuildConfig.VERSION_CODE)
/**
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/DebugMenu.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/DebugMenu.kt
new file mode 100644
index 00000000000..e78673b78a0
--- /dev/null
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/DebugMenu.kt
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package app.lawnchair.lawnicons.ui.components.home
+
+import android.content.Context
+import androidx.compose.foundation.horizontalScroll
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Button
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ModalBottomSheet
+import androidx.compose.material3.Switch
+import androidx.compose.material3.Text
+import androidx.compose.material3.TextButton
+import androidx.compose.material3.rememberModalBottomSheetState
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.unit.dp
+import app.lawnchair.lawnicons.BuildConfig
+import app.lawnchair.lawnicons.R
+import app.lawnchair.lawnicons.model.IconInfoModel
+import app.lawnchair.lawnicons.model.IconRequestModel
+import app.lawnchair.lawnicons.model.splitByComponentName
+import app.lawnchair.lawnicons.repository.BasePreferenceManager
+import app.lawnchair.lawnicons.repository.PreferenceManager
+import app.lawnchair.lawnicons.repository.preferenceManager
+import app.lawnchair.lawnicons.ui.components.core.Card
+import app.lawnchair.lawnicons.ui.components.core.SimpleListRow
+import app.lawnchair.lawnicons.ui.util.copyTextToClipboard
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun DebugMenu(
+ iconInfoModel: IconInfoModel,
+ iconRequestModel: IconRequestModel?,
+ newIconsInfoModel: IconInfoModel,
+) {
+ val context = LocalContext.current
+ val prefs = preferenceManager()
+ val sheetState = rememberModalBottomSheetState(
+ skipPartiallyExpanded = true,
+ )
+
+ ModalBottomSheet(
+ onDismissRequest = { prefs.showDebugMenu.set(false) },
+ sheetState = sheetState,
+ ) {
+ SheetContent(
+ iconInfoCount = iconInfoModel.iconInfo.size,
+ componentCount = iconInfoModel.iconInfo.splitByComponentName().size,
+ newIconInfoList = newIconsInfoModel.toString(),
+ newIconInfoCount = newIconsInfoModel.iconInfo.size,
+ iconRequestList = iconRequestModel?.list?.joinToString("\n") { "${it.label}\n${it.componentName}" }
+ ?: "null",
+ iconRequestCount = iconRequestModel?.iconCount ?: 0,
+ context,
+ prefs,
+ )
+ }
+}
+
+@Composable
+private fun SheetContent(
+ iconInfoCount: Int,
+ componentCount: Int,
+ newIconInfoList: String,
+ newIconInfoCount: Int,
+ iconRequestList: String,
+ iconRequestCount: Int,
+ context: Context,
+ prefs: PreferenceManager,
+) {
+ Column(
+ modifier = Modifier
+ .padding(16.dp)
+ .verticalScroll(rememberScrollState())
+ .fillMaxWidth(),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.spacedBy(12.dp),
+ ) {
+ SimpleListRow("Icon count: $iconInfoCount")
+ SimpleListRow("Component count: $componentCount")
+ SimpleListRow("New icon count: $newIconInfoCount")
+ SimpleListRow("Icon request count: $iconRequestCount")
+
+ SwitchPref(prefs.showDebugMenu)
+ SwitchPref(prefs.showNewIconsCard)
+ SwitchPref(prefs.showFirstLaunchSnackbar)
+
+ SimpleListRow(
+ "Current version",
+ description = prefs.currentLawniconsVersion.asState().value.toString(),
+ )
+ SimpleListRow(
+ "Actual version",
+ description = BuildConfig.VERSION_CODE.toString(),
+ )
+ Button({ prefs.currentLawniconsVersion.set(0) }) { Text("Reset version code") }
+
+ CopyableList(iconRequestList, context)
+ CopyableList(newIconInfoList, context)
+ }
+}
+
+@Composable
+private fun CopyableList(string: String, context: Context) {
+ Card {
+ Column(
+ modifier = Modifier
+ .padding(16.dp),
+ ) {
+ Text(
+ text = string,
+ fontFamily = FontFamily.Monospace,
+ modifier = Modifier
+ .horizontalScroll(rememberScrollState()),
+ )
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.Center,
+ ) {
+ TextButton(
+ onClick = {
+ copyTextToClipboard(context, string)
+ },
+ ) {
+ Text(stringResource(R.string.copy_to_clipboard))
+ }
+ }
+ }
+ }
+}
+
+@Composable
+private fun SwitchPref(
+ pref: BasePreferenceManager.BoolPref,
+ modifier: Modifier = Modifier,
+) {
+ SimpleListRow(
+ pref.key,
+ endIcon = {
+ Switch(
+ checked = pref.asState().value,
+ onCheckedChange = { pref.set(it) },
+ )
+ },
+ modifier = modifier,
+ )
+}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeBottomBar.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeBottomBar.kt
index 28e7cb023ae..d355b29cebf 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeBottomBar.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/HomeBottomBar.kt
@@ -58,9 +58,10 @@ fun HomeBottomBar(
)
}
}
+
IconRequestIconButton(
- iconRequestModel = iconRequestModel,
snackbarHostState = snackbarHostState,
+ iconRequestModel = iconRequestModel,
)
SimpleTooltipBox(
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
index 8e0dd7864be..1962770c55d 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconPreviewGrid.kt
@@ -7,6 +7,7 @@ import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
+import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -53,6 +54,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import app.lawnchair.lawnicons.R
import app.lawnchair.lawnicons.model.IconInfo
+import app.lawnchair.lawnicons.repository.preferenceManager
import app.lawnchair.lawnicons.ui.theme.LawniconsTheme
import app.lawnchair.lawnicons.ui.util.PreviewLawnicons
import app.lawnchair.lawnicons.ui.util.SampleData
@@ -222,10 +224,11 @@ private fun ScrollbarIndicator(
}
}
-@OptIn(ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@Composable
fun AppBarListItem(modifier: Modifier = Modifier) {
val context = LocalContext.current
+ val prefs = preferenceManager(context)
CenterAlignedTopAppBar(
modifier = modifier,
title = {
@@ -236,7 +239,14 @@ fun AppBarListItem(modifier: Modifier = Modifier) {
Image(
bitmap = context.appIcon().asImageBitmap(),
contentDescription = stringResource(id = R.string.app_name),
- modifier = Modifier.size(36.dp),
+ modifier = Modifier
+ .size(36.dp)
+ .combinedClickable(
+ onClick = {},
+ onLongClick = {
+ prefs.showDebugMenu.toggle()
+ },
+ ),
)
}
Spacer(modifier = Modifier.width(8.dp))
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
index 83ce44a0e6d..997f02570d2 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/components/home/IconRequestFAB.kt
@@ -1,61 +1,45 @@
package app.lawnchair.lawnicons.ui.components.home
-import android.content.ClipData
-import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.net.Uri
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.lazy.grid.LazyGridState
-import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FloatingActionButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.ModalBottomSheet
-import androidx.compose.material3.SheetState
+import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult
import androidx.compose.material3.Text
-import androidx.compose.material3.TextButton
-import androidx.compose.material3.rememberModalBottomSheetState
+import androidx.compose.material3.TooltipBox
+import androidx.compose.material3.TooltipDefaults
+import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
-import androidx.compose.runtime.saveable.rememberSaveable
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.platform.ViewConfiguration
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import app.lawnchair.lawnicons.R
import app.lawnchair.lawnicons.model.IconRequest
import app.lawnchair.lawnicons.model.IconRequestModel
import app.lawnchair.lawnicons.repository.preferenceManager
-import app.lawnchair.lawnicons.ui.components.core.Card
import app.lawnchair.lawnicons.ui.util.Constants
+import app.lawnchair.lawnicons.ui.util.copyTextToClipboard
import app.lawnchair.lawnicons.ui.util.isScrollingUp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
@@ -76,6 +60,7 @@ fun IconRequestFAB(
enabled = enabled,
iconRequestList = list,
snackbarHostState = snackbarHostState,
+ onLongClick = {},
) { interactionSource ->
ExtendedFloatingActionButton(
text = {
@@ -96,6 +81,7 @@ fun IconRequestFAB(
}
}
+@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun IconRequestIconButton(
snackbarHostState: SnackbarHostState,
@@ -105,33 +91,52 @@ fun IconRequestIconButton(
val list = iconRequestModel?.list ?: emptyList()
val enabled = iconRequestModel != null
+ val tooltipState = rememberTooltipState()
+ val scope = rememberCoroutineScope()
+
RequestHandler(
enabled = enabled,
iconRequestList = list,
snackbarHostState = snackbarHostState,
+ onLongClick = {
+ scope.launch {
+ tooltipState.show()
+ }
+ },
) { interactionSource ->
- IconButton(
- onClick = {},
- enabled = enabled,
- interactionSource = if (enabled) interactionSource else null,
+ TooltipBox(
+ positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
+ tooltip = {
+ PlainTooltip {
+ Text(stringResource(R.string.request_icons))
+ }
+ },
+ state = tooltipState,
modifier = modifier,
+ enableUserInput = false,
) {
- Icon(
- painter = painterResource(id = R.drawable.icon_request_app),
- contentDescription = stringResource(R.string.request_icons),
- modifier = Modifier.requiredSize(24.dp),
- )
+ IconButton(
+ onClick = {},
+ enabled = enabled,
+ interactionSource = if (enabled) interactionSource else null,
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.icon_request_app),
+ contentDescription = stringResource(R.string.request_icons),
+ modifier = Modifier.requiredSize(24.dp),
+ )
+ }
}
}
}
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun RequestHandler(
enabled: Boolean,
iconRequestList: List,
snackbarHostState: SnackbarHostState,
- content: @Composable ((interactionSource: MutableInteractionSource) -> Unit),
+ onLongClick: () -> Unit,
+ content: @Composable (interactionSource: MutableInteractionSource) -> Unit,
) {
val prefs = preferenceManager()
val showFirstLaunchSnackbar by prefs.showFirstLaunchSnackbar.asState()
@@ -141,11 +146,6 @@ fun RequestHandler(
val encodedRequestList = buildForm(requestList.replace("\n", "%20"))
val directLinkEnabled = encodedRequestList.length < Constants.DIRECT_LINK_MAX_LENGTH
- var sheetExpanded by rememberSaveable { mutableStateOf(false) }
- val sheetState = rememberModalBottomSheetState(
- skipPartiallyExpanded = true,
- )
-
val scope = rememberCoroutineScope()
val interactionSource = remember { MutableInteractionSource() }
@@ -155,12 +155,11 @@ fun RequestHandler(
viewConfiguration = LocalViewConfiguration.current,
context = context,
coroutineScope = scope,
- onExpandSheet = { sheetExpanded = it },
- sheetState = sheetState,
+ onLongClick = onLongClick,
iconRequestList = iconRequestList,
directLinkEnabled = directLinkEnabled,
- encodedRequestList = encodedRequestList,
requestList = requestList,
+ encodedRequestList = encodedRequestList,
snackbarHostState = snackbarHostState,
)
@@ -176,18 +175,8 @@ fun RequestHandler(
)
}
}
-
- AnimatedVisibility(visible = sheetExpanded) {
- ModalBottomSheet(
- onDismissRequest = { sheetExpanded = false },
- sheetState = sheetState,
- ) {
- IconRequestSheet(requestList, context)
- }
- }
}
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun HandleTouchInteractions(
enabled: Boolean,
@@ -195,15 +184,14 @@ private fun HandleTouchInteractions(
viewConfiguration: ViewConfiguration,
context: Context,
coroutineScope: CoroutineScope,
- onExpandSheet: (Boolean) -> Unit,
- sheetState: SheetState,
+ onLongClick: () -> Unit,
iconRequestList: List,
directLinkEnabled: Boolean,
requestList: String,
encodedRequestList: String,
snackbarHostState: SnackbarHostState,
) {
- val lastestOnExpandSheet by rememberUpdatedState(newValue = onExpandSheet)
+ val latestOnClick by rememberUpdatedState(newValue = onLongClick)
if (enabled) {
LaunchedEffect(interactionSource) {
@@ -215,10 +203,7 @@ private fun HandleTouchInteractions(
isLongClick = false
delay(viewConfiguration.longPressTimeoutMillis)
isLongClick = true
- coroutineScope.launch {
- lastestOnExpandSheet(true)
- sheetState.show()
- }
+ latestOnClick()
}
is PressInteraction.Release -> {
@@ -244,52 +229,9 @@ private fun HandleTouchInteractions(
}
}
-@Composable
-private fun IconRequestSheet(list: String, context: Context) {
- Column(
- modifier = Modifier
- .padding(16.dp)
- .fillMaxWidth(),
- horizontalAlignment = Alignment.CenterHorizontally,
- ) {
- Card {
- Column(
- modifier = Modifier
- .verticalScroll(rememberScrollState())
- .padding(16.dp),
- ) {
- Text(
- text = list,
- fontFamily = FontFamily.Monospace,
- modifier = Modifier
- .horizontalScroll(rememberScrollState()),
- )
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.Center,
- ) {
- TextButton(
- onClick = {
- copyTextToClipboard(context, list)
- },
- ) {
- Text(stringResource(R.string.copy_to_clipboard))
- }
- }
- }
- }
- }
-}
-
private fun formatIconRequestList(iconRequestList: List) =
iconRequestList.joinToString("\n") { "${it.label}\n${it.componentName}" }
-private fun copyTextToClipboard(context: Context, text: String) {
- val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
- val clip = ClipData.newPlainText(context.getString(R.string.copied_text), text)
- clipboard.setPrimaryClip(clip)
-}
-
private fun handleRequestClick(
iconRequestList: List,
context: Context,
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
index 52ada0381f2..447e22ae4f7 100644
--- a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/destination/Home.kt
@@ -25,7 +25,9 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import app.lawnchair.lawnicons.model.IconInfo
+import app.lawnchair.lawnicons.repository.preferenceManager
import app.lawnchair.lawnicons.ui.components.home.AppBarListItem
+import app.lawnchair.lawnicons.ui.components.home.DebugMenu
import app.lawnchair.lawnicons.ui.components.home.HomeBottomBar
import app.lawnchair.lawnicons.ui.components.home.HomeTopBar
import app.lawnchair.lawnicons.ui.components.home.HomeTopBarUiState
@@ -127,8 +129,8 @@ private fun Home(
if (isExpandedScreen) {
IconRequestFAB(
iconRequestModel = iconRequestModel,
- snackbarHostState = snackbarHostState,
lazyGridState = lazyGridState,
+ snackbarHostState = snackbarHostState,
)
}
},
@@ -172,6 +174,14 @@ private fun Home(
focusRequester.requestFocus()
}
}
+ val prefs = preferenceManager(context)
+ if (prefs.showDebugMenu.asState().value) {
+ DebugMenu(
+ iconInfoModel,
+ iconRequestModel,
+ newIconsInfoModel,
+ )
+ }
}
}
diff --git a/app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/Clipboard.kt b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/Clipboard.kt
new file mode 100644
index 00000000000..05c98b9ac5c
--- /dev/null
+++ b/app/src/main/kotlin/app/lawnchair/lawnicons/ui/util/Clipboard.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2024 Lawnchair Launcher
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package app.lawnchair.lawnicons.ui.util
+
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.Context
+import app.lawnchair.lawnicons.R
+
+fun copyTextToClipboard(context: Context, text: String) {
+ val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
+ val clip = ClipData.newPlainText(context.getString(R.string.copied_text), text)
+ clipboard.setPrimaryClip(clip)
+}
From f8853ac1573631d43a1d62e205072046f8531fd5 Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Mon, 9 Sep 2024 23:09:17 +0800
Subject: [PATCH 115/144] Fix workflow
---
.github/workflows/build_debug_apk.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/build_debug_apk.yml b/.github/workflows/build_debug_apk.yml
index 23f1856941b..2cb49104ead 100644
--- a/.github/workflows/build_debug_apk.yml
+++ b/.github/workflows/build_debug_apk.yml
@@ -16,6 +16,8 @@ jobs:
uses: actions/checkout@v4
with:
submodules: true
+ - name: Fetch main branch
+ run: git fetch origin main:main
- uses: actions/setup-java@v4
with:
distribution: 'zulu'
From 2dbb2fcabcba838aa0a0594bd37a120e8d5cd657 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Tue, 10 Sep 2024 08:30:35 +0800
Subject: [PATCH 116/144] Update dependency gradle to v8.10.1 (#2317)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
gradle/wrapper/gradle-wrapper.properties | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 2b189974c29..8e876e1c557 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionSha256Sum=5b9c5eb3f9fc2c94abaea57d90bd78747ca117ddbbf96c859d3741181a12bf2a
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
+distributionSha256Sum=1541fa36599e12857140465f3c91a97409b4512501c26f9631fb113e392c5bd1
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
From 15ef5c3ee348a08b820c355cdb223089c97c2f0a Mon Sep 17 00:00:00 2001
From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com>
Date: Tue, 10 Sep 2024 18:56:41 +0800
Subject: [PATCH 117/144] Update app icon
---
app/src/main/ic_launcher-playstore.png | Bin 197681 -> 23303 bytes
.../drawable-v24/ic_launcher_foreground.xml | 30 ---
.../res/drawable/ic_launcher_background.xml | 197 +++---------------
.../res/drawable/ic_launcher_foreground.xml | 15 ++
.../res/drawable/ic_launcher_monochrome.xml | 27 +--
.../res/mipmap-anydpi-v26/ic_launcher.xml | 7 +-
.../mipmap-anydpi-v26/ic_launcher_round.xml | 7 +-
app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 5562 -> 3057 bytes
.../res/mipmap-hdpi/ic_launcher_round.png | Bin 7567 -> 5058 bytes
app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 3324 -> 2266 bytes
.../res/mipmap-mdpi/ic_launcher_round.png | Bin 4351 -> 3193 bytes
app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 8685 -> 4158 bytes
.../res/mipmap-xhdpi/ic_launcher_round.png | Bin 11813 -> 7191 bytes
.../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 16344 -> 6443 bytes
.../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 22027 -> 11279 bytes
.../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 26957 -> 8455 bytes
.../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 35179 -> 15862 bytes
17 files changed, 61 insertions(+), 222 deletions(-)
delete mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml
create mode 100644 app/src/main/res/drawable/ic_launcher_foreground.xml
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
index a0c46279ed9d90e7668d9621b280f121213f07b1..a41561910c88a7af95c02c1c56d1107a6f8fd499 100644
GIT binary patch
literal 23303
zcmce-XIRs1^EMc2=qN>yE*mEJ@|inLHA)DWt45$PqN
zijYv!Dp^O|4W69X-33Kj|g06?w%_|Y=}fDr#D
zA%Kh&|8pGh>kkgJ=UO3RJ+xx7Yizn3C)k&w4$>y*9C
zD#7ev`&pfk_YQAiUiaP2y!t1j3Y+>;tPT@blZ#c2o+po6g-7&E4UuEbVXDCgIu(D+
z3{71oPleSVJ$kfKoPNcL|K-IA5!|?WGp^9YwKeOXf0(2JVq;@_-q8VW-h9vejF5|)
zo9>|w06+HSWAgCW*vC}=&bY$|;O6F*{6dUhjyL*$VbYU|Z{VE&ZCn2;cXc?5`YU1l
z|4s?>hiUQJq7(lAN0BcUovyY1-m1p`yrDvqCO>I4yr_>W1^>C^|Ie=M|JFG0TZh?%
z;SKA(+0*}*7BmVglG;}{MU6uvI8RAGvQlAfsP^|>p;B+Fmo}?wt)^yg!1W21ShjJu
zug$OXfgShYMMnE)@v)Ebrz0m3-bv9fRt-~;a965vp{;RJt2qVKT;HfUkf_-etZ8MQ
z0aLK)0JMfeVm@3$=8bm#S%v-D@|xzlx_QGt*#g)gh3i{YiNbZnK3)(acvtB(KaMMh
z*fRVGCa(!#s(IA}e#$9Ga`&0KKKm17cp?de3E~hqh?ASzIm3-;C`E+nM#%M_SCROc
zYdl(cL>~T%Eq56*NBbK-9I}Ys7rv_6&}}ax{BEs+TzM^l3-EjkzLgOtO8d|Rp!TPz
zn&@U6Cm-O$%`+bYD>fP`iS+AX(au8^b?stHl2)d;yVhH7@L{4%BJpfn7-k4{5Qo{5
zIYSwRhJ&dIt%Lwe9F$mB?)@|6UfW;?w*5IWh{$jX=CaE5H1MXvO+J9vpqm_c#4v|x
zuT(0+F*jlob44LD48mPBQ=Gx}evoqJS1ca5*Mbvmke@6-sM8OY)n=X{F
zgV4&k4zKvWvdRN`5`GOM*^9C5{)vcIMc^2;$EdrQ|;T9j0?>Hyg7
z6<;NH$~V%S8SsRVOTT4P7sYOLz*I>n%XSFv@=SPM1=%Um(>Tru^jsS9By=22&+BN_
zD?V-_594cm3B{$45#+@WYZzA{eLFqH(S{^@_7&R_;PT{i1hLVfa?jqs8ba@)+{
z*WO@mrefo3GwQ0S_uw=@&yOohtcE(Q*NxwQ*$C?|ZBV_haAQ%h@I{SIqrfG)&aYums(#
ziT+&TAt1l^fk;Aup9?%~h4bXJUQon*XS}$TDn~eWOlt*+Bjp1Gme(F4J%__yF;)|2
z-rRsChUgN`pm75}nAeOKEQ?HpXTIc1z!g>e$gKimD|-YmMgHR>R@%LbFlr?w%kJomeOgvc;)N>9xDrM5ts064}B9K
zlH!<)ZD-%X++X-BV2yV6l~?@h-j)1L9*~{rh)fd2x0fMbF0N~--FWSh^eeLX?ccEe
zpaQw6WyF^ePm{-b(e0nUwst5CeI5_%`N)l0)J9+)EEE%S87|Dv7Gzdb85gnUaevo0
z-CG@XcC4-)a>I3jcWdtJ>h{Y9>|#Vo_Es7?rO#qvTIA{+))U*TJP~(A(X1CJx)E{e
zBjM*5#nzqnffxH)%e2bZ^KVdBcif&4z5~Kg6u=KchdeX_;b0mvD+g20J6U2!$0yKz
z2VxIl7YxTuIU#~r*d{3