reformat code

This commit is contained in:
2026-07-24 14:36:39 +03:00
parent 6ef0132bcc
commit 64603dc368
46 changed files with 445 additions and 337 deletions
@@ -1,4 +1,3 @@
import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.ApplicationExtension
plugins { plugins {
@@ -20,7 +20,11 @@ fun Route.setupSearch(searchFactory: SearchRepositoryFactory) {
val p = call.parameters val p = call.parameters
val userId = call.obtainUserId() val userId = call.obtainUserId()
val search = searchFactory.create(userId) val search = searchFactory.create(userId)
call.respond(SearchQueryResponse(search.search(p[SearchRepository.QUERY_ARG] ?: "").first())) call.respond(
SearchQueryResponse(
search.search(p[SearchRepository.QUERY_ARG] ?: "").first()
)
)
} }
post(SearchRepository.ADD_TO_SEARCH) { post(SearchRepository.ADD_TO_SEARCH) {
val userId = call.obtainUserId() val userId = call.obtainUserId()
@@ -3,7 +3,8 @@
<base-config> <base-config>
<trust-anchors> <trust-anchors>
<certificates src="system" /> <certificates src="system" />
<certificates src="user" <certificates
src="user"
tools:ignore="AcceptsUserCertificates" /> tools:ignore="AcceptsUserCertificates" />
</trust-anchors> </trust-anchors>
</base-config> </base-config>
@@ -18,9 +18,9 @@
android:enableOnBackInvokedCallback="true" android:enableOnBackInvokedCallback="true"
android:icon="@mipmap/pig_launcher" android:icon="@mipmap/pig_launcher"
android:label="@string/app_name_pig" android:label="@string/app_name_pig"
android:networkSecurityConfig="@xml/network_security_config"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.Videobox" android:theme="@style/Theme.Videobox"
android:networkSecurityConfig="@xml/network_security_config"
tools:ignore="UnusedAttribute"> tools:ignore="UnusedAttribute">
<activity <activity
@@ -19,7 +19,8 @@ open class PigReceiver : BroadcastReceiver() {
val pm = context.packageManager val pm = context.packageManager
val mainActivity = ComponentName(context, MainActivity::class.java) val mainActivity = ComponentName(context, MainActivity::class.java)
val piggyActivityAlias = ComponentName(context, PIGGY_CLS) val piggyActivityAlias = ComponentName(context, PIGGY_CLS)
val isMainEnabled = pm.getComponentEnabledSetting(mainActivity) == PackageManager.COMPONENT_ENABLED_STATE_ENABLED val isMainEnabled =
pm.getComponentEnabledSetting(mainActivity) == PackageManager.COMPONENT_ENABLED_STATE_ENABLED
pm.setState(piggyActivityAlias, isMainEnabled) pm.setState(piggyActivityAlias, isMainEnabled)
pm.setState(mainActivity, !isMainEnabled) pm.setState(mainActivity, !isMainEnabled)
} }
@@ -4,138 +4,162 @@
android:height="180dp" android:height="180dp"
android:viewportWidth="471" android:viewportWidth="471"
android:viewportHeight="458"> android:viewportHeight="458">
<group android:scaleX="0.6666667" <group
android:scaleX="0.6666667"
android:scaleY="0.6666667" android:scaleY="0.6666667"
android:translateX="78.5" android:translateX="78.5"
android:translateY="76.333336"> android:translateY="76.333336">
<group android:scaleX="0.3470797" <group
android:scaleX="0.3470797"
android:scaleY="0.6" android:scaleY="0.6"
android:translateX="26.592731" android:translateX="26.592731"
android:translateY="91.6"> android:translateY="91.6">
<path <path
android:pathData="M197.58,203.61C170.88,160.97 122.56,149.44 92.05,188.63C74.25,212.83 70.43,237.04 45,250.87C31.02,258.93 33.56,276.22 50.09,281.99C84.42,294.66 140.36,278.53 168.34,250.87C186.14,233.58 195.04,217.44 197.58,203.61Z"
android:strokeLineJoin="round"
android:strokeWidth="7"
android:fillColor="#FFE1D8" android:fillColor="#FFE1D8"
android:pathData="M197.58,203.61C170.88,160.97 122.56,149.44 92.05,188.63C74.25,212.83 70.43,237.04 45,250.87C31.02,258.93 33.56,276.22 50.09,281.99C84.42,294.66 140.36,278.53 168.34,250.87C186.14,233.58 195.04,217.44 197.58,203.61Z"
android:strokeWidth="7"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"/> android:strokeLineCap="round"
<path android:strokeLineJoin="round" />
android:pathData="M155.94,188.24C126.64,181.34 101.52,196.53 84.78,225.53C73.62,243.48 62.45,258.67 49.89,268.34C76.41,276.63 122.45,268.34 150.36,240.72C167.1,224.15 174.08,204.82 155.94,188.24Z"> <path android:pathData="M155.94,188.24C126.64,181.34 101.52,196.53 84.78,225.53C73.62,243.48 62.45,258.67 49.89,268.34C76.41,276.63 122.45,268.34 150.36,240.72C167.1,224.15 174.08,204.82 155.94,188.24Z">
<aapt:attr name="android:fillColor"> <aapt:attr name="android:fillColor">
<gradient <gradient
android:startX="91.76"
android:startY="174.43"
android:endX="161.85" android:endX="161.85"
android:endY="291.08" android:endY="291.08"
android:startX="91.76"
android:startY="174.43"
android:type="linear"> android:type="linear">
<item android:offset="0" android:color="#FFF8B3AD"/> <item
<item android:offset="1" android:color="#FFF2A099"/> android:color="#FFF8B3AD"
android:offset="0" />
<item
android:color="#FFF2A099"
android:offset="1" />
</gradient> </gradient>
</aapt:attr> </aapt:attr>
</path> </path>
<path <path
android:pathData="M273.42,203.61C300.12,160.97 348.44,149.44 378.95,188.63C396.75,212.83 400.57,237.04 426,250.87C439.98,258.93 437.44,276.22 420.91,281.99C386.58,294.66 330.64,278.53 302.66,250.87C284.86,233.58 275.96,217.44 273.42,203.61Z"
android:strokeLineJoin="round"
android:strokeWidth="7"
android:fillColor="#FFE1D8" android:fillColor="#FFE1D8"
android:pathData="M273.42,203.61C300.12,160.97 348.44,149.44 378.95,188.63C396.75,212.83 400.57,237.04 426,250.87C439.98,258.93 437.44,276.22 420.91,281.99C386.58,294.66 330.64,278.53 302.66,250.87C284.86,233.58 275.96,217.44 273.42,203.61Z"
android:strokeWidth="7"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"/> android:strokeLineCap="round"
android:strokeLineJoin="round" />
<path <path
android:pathData="M313.06,188.24C342.36,181.34 367.48,196.53 384.23,225.53C395.39,243.48 406.55,258.67 419.11,268.34C392.6,276.63 346.55,268.34 318.64,240.72C301.9,224.15 294.92,204.82 313.06,188.24Z" android:fillColor="#F2AAA3"
android:fillColor="#F2AAA3"/> android:pathData="M313.06,188.24C342.36,181.34 367.48,196.53 384.23,225.53C395.39,243.48 406.55,258.67 419.11,268.34C392.6,276.63 346.55,268.34 318.64,240.72C301.9,224.15 294.92,204.82 313.06,188.24Z" />
<path <path
android:pathData="M149.68,219.53C149.68,174.25 187.7,150.67 235.5,150.67C283.3,150.67 321.32,174.25 321.32,219.53V258.2C321.32,313.85 281.13,340.26 235.5,340.26C189.88,340.26 149.68,313.85 149.68,258.2V219.53Z" android:pathData="M149.68,219.53C149.68,174.25 187.7,150.67 235.5,150.67C283.3,150.67 321.32,174.25 321.32,219.53V258.2C321.32,313.85 281.13,340.26 235.5,340.26C189.88,340.26 149.68,313.85 149.68,258.2V219.53Z"
android:strokeLineJoin="round"
android:strokeWidth="7" android:strokeWidth="7"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"> android:strokeLineCap="round"
android:strokeLineJoin="round">
<aapt:attr name="android:fillColor"> <aapt:attr name="android:fillColor">
<gradient <gradient
android:centerX="235.5" android:centerX="235.5"
android:centerY="210.09" android:centerY="210.09"
android:gradientRadius="124.5" android:gradientRadius="124.5"
android:type="radial"> android:type="radial">
<item android:offset="0" android:color="#FFFFEFE8"/> <item
<item android:offset="1" android:color="#FFFFD8CE"/> android:color="#FFFFEFE8"
android:offset="0" />
<item
android:color="#FFFFD8CE"
android:offset="1" />
</gradient> </gradient>
</aapt:attr> </aapt:attr>
</path> </path>
<path <path
android:pathData="M197.96,203.74C203.68,203.74 208.32,199.23 208.32,193.67C208.32,188.11 203.68,183.6 197.96,183.6C192.24,183.6 187.6,188.11 187.6,193.67C187.6,199.23 192.24,203.74 197.96,203.74Z" android:fillColor="#5A4844"
android:fillColor="#5A4844"/> android:pathData="M197.96,203.74C203.68,203.74 208.32,199.23 208.32,193.67C208.32,188.11 203.68,183.6 197.96,183.6C192.24,183.6 187.6,188.11 187.6,193.67C187.6,199.23 192.24,203.74 197.96,203.74Z" />
<path <path
android:pathData="M270.8,203.74C276.52,203.74 281.16,199.23 281.16,193.67C281.16,188.11 276.52,183.6 270.8,183.6C265.08,183.6 260.45,188.11 260.45,193.67C260.45,199.23 265.08,203.74 270.8,203.74Z" android:fillColor="#5A4844"
android:fillColor="#5A4844"/> android:pathData="M270.8,203.74C276.52,203.74 281.16,199.23 281.16,193.67C281.16,188.11 276.52,183.6 270.8,183.6C265.08,183.6 260.45,188.11 260.45,193.67C260.45,199.23 265.08,203.74 270.8,203.74Z" />
<path <path
android:pathData="M237.5,318.3C278.28,318.3 311.34,292.62 311.34,260.93C311.34,229.24 278.28,203.56 237.5,203.56C196.71,203.56 163.65,229.24 163.65,260.93C163.65,292.62 196.71,318.3 237.5,318.3Z" android:pathData="M237.5,318.3C278.28,318.3 311.34,292.62 311.34,260.93C311.34,229.24 278.28,203.56 237.5,203.56C196.71,203.56 163.65,229.24 163.65,260.93C163.65,292.62 196.71,318.3 237.5,318.3Z"
android:strokeLineJoin="round"
android:strokeWidth="5" android:strokeWidth="5"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"> android:strokeLineCap="round"
android:strokeLineJoin="round">
<aapt:attr name="android:fillColor"> <aapt:attr name="android:fillColor">
<gradient <gradient
android:centerX="237.5" android:centerX="237.5"
android:centerY="242.68" android:centerY="242.68"
android:gradientRadius="88.67" android:gradientRadius="88.67"
android:type="radial"> android:type="radial">
<item android:offset="0" android:color="#FFFFC4C1"/> <item
<item android:offset="1" android:color="#FFF6A5A5"/> android:color="#FFFFC4C1"
android:offset="0" />
<item
android:color="#FFF6A5A5"
android:offset="1" />
</gradient> </gradient>
</aapt:attr> </aapt:attr>
</path> </path>
<path <path
android:pathData="M204.07,286.38C218.67,286.38 230.51,274.98 230.51,260.93C230.51,246.88 218.67,235.49 204.07,235.49C189.46,235.49 177.62,246.88 177.62,260.93C177.62,274.98 189.46,286.38 204.07,286.38Z" android:fillColor="#4E403D"
android:fillColor="#4E403D"/> android:pathData="M204.07,286.38C218.67,286.38 230.51,274.98 230.51,260.93C230.51,246.88 218.67,235.49 204.07,235.49C189.46,235.49 177.62,246.88 177.62,260.93C177.62,274.98 189.46,286.38 204.07,286.38Z" />
<path <path
android:pathData="M269.93,286.38C284.53,286.38 296.37,274.98 296.37,260.93C296.37,246.88 284.53,235.49 269.93,235.49C255.32,235.49 243.48,246.88 243.48,260.93C243.48,274.98 255.32,286.38 269.93,286.38Z" android:fillColor="#4E403D"
android:fillColor="#4E403D"/> android:pathData="M269.93,286.38C284.53,286.38 296.37,274.98 296.37,260.93C296.37,246.88 284.53,235.49 269.93,235.49C255.32,235.49 243.48,246.88 243.48,260.93C243.48,274.98 255.32,286.38 269.93,286.38Z" />
<path <path
android:pathData="M278.41,274.97C275.1,274.97 272.42,272.29 272.42,268.98V253.02C272.42,249.71 275.1,247.03 278.41,247.03C281.72,247.03 284.4,249.71 284.4,253.02V268.98C284.4,272.29 281.72,274.97 278.41,274.97ZM262.44,274.97C259.14,274.97 256.46,272.29 256.46,268.98V253.02C256.46,249.71 259.14,247.03 262.44,247.03C265.75,247.03 268.43,249.71 268.43,253.02V268.98C268.43,272.29 265.75,274.97 262.44,274.97ZM276.41,268.98C276.41,270.08 277.31,270.98 278.41,270.98C279.51,270.98 280.4,270.08 280.4,268.98V253.02C280.4,251.91 279.51,251.02 278.41,251.02C277.31,251.02 276.41,251.91 276.41,253.02V268.98ZM260.45,268.98C260.45,270.08 261.34,270.98 262.44,270.98C263.55,270.98 264.44,270.08 264.44,268.98V253.02C264.44,251.91 263.55,251.02 262.44,251.02C261.34,251.02 260.45,251.91 260.45,253.02V268.98Z" android:fillColor="#FFD9D0"
android:fillColor="#FFD9D0"/> android:pathData="M278.41,274.97C275.1,274.97 272.42,272.29 272.42,268.98V253.02C272.42,249.71 275.1,247.03 278.41,247.03C281.72,247.03 284.4,249.71 284.4,253.02V268.98C284.4,272.29 281.72,274.97 278.41,274.97ZM262.44,274.97C259.14,274.97 256.46,272.29 256.46,268.98V253.02C256.46,249.71 259.14,247.03 262.44,247.03C265.75,247.03 268.43,249.71 268.43,253.02V268.98C268.43,272.29 265.75,274.97 262.44,274.97ZM276.41,268.98C276.41,270.08 277.31,270.98 278.41,270.98C279.51,270.98 280.4,270.08 280.4,268.98V253.02C280.4,251.91 279.51,251.02 278.41,251.02C277.31,251.02 276.41,251.91 276.41,253.02V268.98ZM260.45,268.98C260.45,270.08 261.34,270.98 262.44,270.98C263.55,270.98 264.44,270.08 264.44,268.98V253.02C264.44,251.91 263.55,251.02 262.44,251.02C261.34,251.02 260.45,251.91 260.45,253.02V268.98Z" />
<path <path
android:pathData="M198.66,276.05C197.33,276.9 195.59,275.95 195.59,274.37V248.63C195.59,247.05 197.33,246.1 198.66,246.95L218.88,259.81C220.11,260.6 220.11,262.4 218.88,263.19L198.66,276.05ZM200.3,265.75C200.3,267.33 202.05,268.29 203.38,267.44L210.04,263.19C211.27,262.4 211.27,260.6 210.04,259.81L203.38,255.56C202.05,254.71 200.3,255.67 200.3,257.25V265.75Z" android:fillColor="#FFDAD0"
android:fillColor="#FFDAD0"/> android:pathData="M198.66,276.05C197.33,276.9 195.59,275.95 195.59,274.37V248.63C195.59,247.05 197.33,246.1 198.66,246.95L218.88,259.81C220.11,260.6 220.11,262.4 218.88,263.19L198.66,276.05ZM200.3,265.75C200.3,267.33 202.05,268.29 203.38,267.44L210.04,263.19C211.27,262.4 211.27,260.6 210.04,259.81L203.38,255.56C202.05,254.71 200.3,255.67 200.3,257.25V265.75Z" />
<path <path
android:fillColor="#00000000"
android:pathData="M150,218.85C150,173.58 188.02,150 235.82,150C283.61,150 321.64,173.58 321.64,218.85V257.53C321.64,313.18 281.44,339.59 235.82,339.59C190.19,339.59 150,313.18 150,257.53V218.85Z" android:pathData="M150,218.85C150,173.58 188.02,150 235.82,150C283.61,150 321.64,173.58 321.64,218.85V257.53C321.64,313.18 281.44,339.59 235.82,339.59C190.19,339.59 150,313.18 150,257.53V218.85Z"
android:strokeLineJoin="round"
android:strokeWidth="7" android:strokeWidth="7"
android:fillColor="#00000000"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"/> android:strokeLineCap="round"
android:strokeLineJoin="round" />
<path <path
android:pathData="M237.84,317.75C278.63,317.75 311.69,292.06 311.69,260.37C311.69,228.69 278.63,203 237.84,203C197.06,203 164,228.69 164,260.37C164,292.06 197.06,317.75 237.84,317.75Z"
android:strokeLineJoin="round"
android:strokeWidth="5"
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M237.84,317.75C278.63,317.75 311.69,292.06 311.69,260.37C311.69,228.69 278.63,203 237.84,203C197.06,203 164,228.69 164,260.37C164,292.06 197.06,317.75 237.84,317.75Z"
android:strokeWidth="5"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"/> android:strokeLineCap="round"
android:strokeLineJoin="round" />
</group> </group>
<group android:scaleX="0.492" <group
android:scaleX="0.492"
android:scaleY="0.14991412" android:scaleY="0.14991412"
android:translateX="391.2" android:translateX="391.2"
android:translateY="71.247826"> android:translateY="71.247826">
<group android:translateY="133.66406"> <group android:translateY="133.66406">
<path android:pathData="M92.75,-96.890625L92.75,-81.921875Q85.578125,-88.59375,77.453125,-91.890625Q69.328125,-95.203125,60.1875,-95.203125Q42.1875,-95.203125,32.625,-84.203125Q23.0625,-73.203125,23.0625,-52.390625Q23.0625,-31.640625,32.625,-20.640625Q42.1875,-9.640625,60.1875,-9.640625Q69.328125,-9.640625,77.453125,-12.9375Q85.578125,-16.25,92.75,-22.921875L92.75,-8.09375Q85.296875,-3.03125,76.953125,-0.484375Q68.625,2.046875,59.34375,2.046875Q35.515625,2.046875,21.796875,-12.546875Q8.09375,-27.140625,8.09375,-52.390625Q8.09375,-77.703125,21.796875,-92.28125Q35.515625,-106.875,59.34375,-106.875Q68.765625,-106.875,77.09375,-104.375Q85.4375,-101.890625,92.75,-96.890625Z" <path
android:fillColor="#000000"/> android:fillColor="#000000"
<path android:pathData="M127.015625,-36.28125L127.015625,-10.34375L145.4375,-10.34375Q154.29688,-10.34375,158.9375,-13.671875Q163.57812,-17.015625,163.57812,-23.34375Q163.57812,-29.671875,158.9375,-32.96875Q154.29688,-36.28125,145.4375,-36.28125L127.015625,-36.28125ZM127.015625,-68.421875L127.015625,-46.625L144.03125,-46.625Q151.34375,-46.625,155.98438,-49.53125Q160.625,-52.453125,160.625,-57.65625Q160.625,-62.859375,155.98438,-65.640625Q151.34375,-68.421875,144.03125,-68.421875L127.015625,-68.421875ZM114.078125,-78.75L144.875,-78.75Q158.73438,-78.75,166.1875,-73.6875Q173.64062,-68.625,173.64062,-59.28125Q173.64062,-52.03125,169.84375,-47.78125Q166.04688,-43.53125,158.59375,-42.46875Q167.51562,-40.78125,172.4375,-35.4375Q177.35938,-30.09375,177.35938,-22.078125Q177.35938,-11.53125,169.23438,-5.765625Q161.125,0,146.07812,0L114.078125,0L114.078125,-78.75Z" android:pathData="M92.75,-96.890625L92.75,-81.921875Q85.578125,-88.59375,77.453125,-91.890625Q69.328125,-95.203125,60.1875,-95.203125Q42.1875,-95.203125,32.625,-84.203125Q23.0625,-73.203125,23.0625,-52.390625Q23.0625,-31.640625,32.625,-20.640625Q42.1875,-9.640625,60.1875,-9.640625Q69.328125,-9.640625,77.453125,-12.9375Q85.578125,-16.25,92.75,-22.921875L92.75,-8.09375Q85.296875,-3.03125,76.953125,-0.484375Q68.625,2.046875,59.34375,2.046875Q35.515625,2.046875,21.796875,-12.546875Q8.09375,-27.140625,8.09375,-52.390625Q8.09375,-77.703125,21.796875,-92.28125Q35.515625,-106.875,59.34375,-106.875Q68.765625,-106.875,77.09375,-104.375Q85.4375,-101.890625,92.75,-96.890625Z" />
android:fillColor="#000000"/> <path
<path android:pathData="M266.51562,-78.75L266.51562,0L253.64062,0L253.64062,-63.21875L215.67188,0L199.07812,0L199.07812,-78.75L211.95312,-78.75L211.95312,-15.6875L249.84375,-78.75L266.51562,-78.75Z" android:fillColor="#000000"
android:fillColor="#000000"/> android:pathData="M127.015625,-36.28125L127.015625,-10.34375L145.4375,-10.34375Q154.29688,-10.34375,158.9375,-13.671875Q163.57812,-17.015625,163.57812,-23.34375Q163.57812,-29.671875,158.9375,-32.96875Q154.29688,-36.28125,145.4375,-36.28125L127.015625,-36.28125ZM127.015625,-68.421875L127.015625,-46.625L144.03125,-46.625Q151.34375,-46.625,155.98438,-49.53125Q160.625,-52.453125,160.625,-57.65625Q160.625,-62.859375,155.98438,-65.640625Q151.34375,-68.421875,144.03125,-68.421875L127.015625,-68.421875ZM114.078125,-78.75L144.875,-78.75Q158.73438,-78.75,166.1875,-73.6875Q173.64062,-68.625,173.64062,-59.28125Q173.64062,-52.03125,169.84375,-47.78125Q166.04688,-43.53125,158.59375,-42.46875Q167.51562,-40.78125,172.4375,-35.4375Q177.35938,-30.09375,177.35938,-22.078125Q177.35938,-11.53125,169.23438,-5.765625Q161.125,0,146.07812,0L114.078125,0L114.078125,-78.75Z" />
<path android:pathData="M292.07812,-78.75L305.09375,-78.75L305.09375,-46.625L347.0625,-46.625L347.0625,-78.75L360.07812,-78.75L360.07812,0L347.0625,0L347.0625,-36.28125L305.09375,-36.28125L305.09375,0L292.07812,0L292.07812,-78.75Z" <path
android:fillColor="#000000"/> android:fillColor="#000000"
<path android:pathData="M417.09375,-69.6875Q406.6875,-69.6875,400.64062,-61.5625Q394.59375,-53.4375,394.59375,-39.3125Q394.59375,-25.171875,400.59375,-17.046875Q406.60938,-8.9375,417.09375,-8.9375Q427.42188,-8.9375,433.46875,-17.09375Q439.51562,-25.25,439.51562,-39.3125Q439.51562,-53.296875,433.46875,-61.484375Q427.42188,-69.6875,417.09375,-69.6875ZM417.09375,-80.65625Q433.96875,-80.65625,443.59375,-69.6875Q453.23438,-58.71875,453.23438,-39.3125Q453.23438,-19.96875,443.59375,-8.953125Q433.96875,2.046875,417.09375,2.046875Q400.14062,2.046875,390.54688,-8.953125Q380.95312,-19.96875,380.95312,-39.3125Q380.95312,-58.71875,390.54688,-69.6875Q400.14062,-80.65625,417.09375,-80.65625Z" android:pathData="M266.51562,-78.75L266.51562,0L253.64062,0L253.64062,-63.21875L215.67188,0L199.07812,0L199.07812,-78.75L211.95312,-78.75L211.95312,-15.6875L249.84375,-78.75L266.51562,-78.75Z" />
android:fillColor="#000000"/> <path
<path android:pathData="M541.9375,-42.609375L541.9375,-36.28125L482.45312,-36.28125Q483.29688,-22.921875,490.5,-15.921875Q497.70312,-8.9375,510.57812,-8.9375Q518.03125,-8.9375,525.0156,-10.765625Q532.0156,-12.59375,538.90625,-16.25L538.90625,-4.015625Q531.9531,-1.0625,524.6406,0.484375Q517.3281,2.046875,509.79688,2.046875Q490.95312,2.046875,479.95312,-8.921875Q468.95312,-19.90625,468.95312,-38.609375Q468.95312,-57.9375,479.39062,-69.296875Q489.82812,-80.65625,507.54688,-80.65625Q523.4375,-80.65625,532.6875,-70.421875Q541.9375,-60.1875,541.9375,-42.609375ZM529,-46.40625Q528.8594,-57.03125,523.0469,-63.359375Q517.25,-69.6875,507.6875,-69.6875Q496.85938,-69.6875,490.35938,-63.5625Q483.85938,-57.453125,482.875,-46.34375L529,-46.40625Z" android:fillColor="#000000"
android:fillColor="#000000"/> android:pathData="M292.07812,-78.75L305.09375,-78.75L305.09375,-46.625L347.0625,-46.625L347.0625,-78.75L360.07812,-78.75L360.07812,0L347.0625,0L347.0625,-36.28125L305.09375,-36.28125L305.09375,0L292.07812,0L292.07812,-78.75Z" />
<path android:pathData="M624.34375,-93.3125L624.34375,-53.859375L642.2031,-53.859375Q652.1094,-53.859375,657.5156,-58.984375Q662.9375,-64.125,662.9375,-73.625Q662.9375,-83.046875,657.5156,-88.171875Q652.1094,-93.3125,642.2031,-93.3125L624.34375,-93.3125ZM610.1406,-104.984375L642.2031,-104.984375Q659.84375,-104.984375,668.875,-97Q677.9219,-89.015625,677.9219,-73.625Q677.9219,-58.078125,668.875,-50.125Q659.84375,-42.1875,642.2031,-42.1875L624.34375,-42.1875L624.34375,0L610.1406,0L610.1406,-104.984375Z" <path
android:fillColor="#000000"/> android:fillColor="#000000"
<path android:pathData="M770.96875,-78.75L783.90625,-78.75L783.90625,0L770.96875,0L770.96875,-78.75ZM777.4375,-80.65625L777.4375,-80.65625ZM745.5781,-23.34375Q745.5781,-29.671875,740.96875,-32.96875Q736.375,-36.28125,727.5156,-36.28125L709.09375,-36.28125L709.09375,-10.34375L727.5156,-10.34375Q736.375,-10.34375,740.96875,-13.671875Q745.5781,-17.015625,745.5781,-23.34375ZM696.0781,-78.75L709.09375,-78.75L709.09375,-46.625L728.0781,-46.625Q743.125,-46.625,751.2344,-40.890625Q759.3594,-35.15625,759.3594,-23.34375Q759.3594,-11.53125,751.2344,-5.765625Q743.125,0,728.0781,0L696.0781,0L696.0781,-78.75Z" android:pathData="M417.09375,-69.6875Q406.6875,-69.6875,400.64062,-61.5625Q394.59375,-53.4375,394.59375,-39.3125Q394.59375,-25.171875,400.59375,-17.046875Q406.60938,-8.9375,417.09375,-8.9375Q427.42188,-8.9375,433.46875,-17.09375Q439.51562,-25.25,439.51562,-39.3125Q439.51562,-53.296875,433.46875,-61.484375Q427.42188,-69.6875,417.09375,-69.6875ZM417.09375,-80.65625Q433.96875,-80.65625,443.59375,-69.6875Q453.23438,-58.71875,453.23438,-39.3125Q453.23438,-19.96875,443.59375,-8.953125Q433.96875,2.046875,417.09375,2.046875Q400.14062,2.046875,390.54688,-8.953125Q380.95312,-19.96875,380.95312,-39.3125Q380.95312,-58.71875,390.54688,-69.6875Q400.14062,-80.65625,417.09375,-80.65625Z" />
android:fillColor="#000000"/> <path
<path android:pathData="M802.34375,0L802.34375,-10.765625Q815.1406,-12.734375,819.0781,-21.59375Q823.8594,-34.03125,823.8594,-65.890625L823.8594,-78.75L877.09375,-78.75L877.09375,0L864.15625,0L864.15625,-68.421875L836.7969,-68.421875L836.7969,-60.609375Q836.7969,-30.234375,830.6094,-16.59375Q824,-2.046875,802.34375,0Z" android:fillColor="#000000"
android:fillColor="#000000"/> android:pathData="M541.9375,-42.609375L541.9375,-36.28125L482.45312,-36.28125Q483.29688,-22.921875,490.5,-15.921875Q497.70312,-8.9375,510.57812,-8.9375Q518.03125,-8.9375,525.0156,-10.765625Q532.0156,-12.59375,538.90625,-16.25L538.90625,-4.015625Q531.9531,-1.0625,524.6406,0.484375Q517.3281,2.046875,509.79688,2.046875Q490.95312,2.046875,479.95312,-8.921875Q468.95312,-19.90625,468.95312,-38.609375Q468.95312,-57.9375,479.39062,-69.296875Q489.82812,-80.65625,507.54688,-80.65625Q523.4375,-80.65625,532.6875,-70.421875Q541.9375,-60.1875,541.9375,-42.609375ZM529,-46.40625Q528.8594,-57.03125,523.0469,-63.359375Q517.25,-69.6875,507.6875,-69.6875Q496.85938,-69.6875,490.35938,-63.5625Q483.85938,-57.453125,482.875,-46.34375L529,-46.40625Z" />
<path android:pathData="M934.09375,-69.6875Q923.6875,-69.6875,917.6406,-61.5625Q911.59375,-53.4375,911.59375,-39.3125Q911.59375,-25.171875,917.59375,-17.046875Q923.6094,-8.9375,934.09375,-8.9375Q944.4219,-8.9375,950.46875,-17.09375Q956.5156,-25.25,956.5156,-39.3125Q956.5156,-53.296875,950.46875,-61.484375Q944.4219,-69.6875,934.09375,-69.6875ZM934.09375,-80.65625Q950.96875,-80.65625,960.59375,-69.6875Q970.2344,-58.71875,970.2344,-39.3125Q970.2344,-19.96875,960.59375,-8.953125Q950.96875,2.046875,934.09375,2.046875Q917.1406,2.046875,907.5469,-8.953125Q897.9531,-19.96875,897.9531,-39.3125Q897.9531,-58.71875,907.5469,-69.6875Q917.1406,-80.65625,934.09375,-80.65625Z" <path
android:fillColor="#000000"/> android:fillColor="#000000"
android:pathData="M624.34375,-93.3125L624.34375,-53.859375L642.2031,-53.859375Q652.1094,-53.859375,657.5156,-58.984375Q662.9375,-64.125,662.9375,-73.625Q662.9375,-83.046875,657.5156,-88.171875Q652.1094,-93.3125,642.2031,-93.3125L624.34375,-93.3125ZM610.1406,-104.984375L642.2031,-104.984375Q659.84375,-104.984375,668.875,-97Q677.9219,-89.015625,677.9219,-73.625Q677.9219,-58.078125,668.875,-50.125Q659.84375,-42.1875,642.2031,-42.1875L624.34375,-42.1875L624.34375,0L610.1406,0L610.1406,-104.984375Z" />
<path
android:fillColor="#000000"
android:pathData="M770.96875,-78.75L783.90625,-78.75L783.90625,0L770.96875,0L770.96875,-78.75ZM777.4375,-80.65625L777.4375,-80.65625ZM745.5781,-23.34375Q745.5781,-29.671875,740.96875,-32.96875Q736.375,-36.28125,727.5156,-36.28125L709.09375,-36.28125L709.09375,-10.34375L727.5156,-10.34375Q736.375,-10.34375,740.96875,-13.671875Q745.5781,-17.015625,745.5781,-23.34375ZM696.0781,-78.75L709.09375,-78.75L709.09375,-46.625L728.0781,-46.625Q743.125,-46.625,751.2344,-40.890625Q759.3594,-35.15625,759.3594,-23.34375Q759.3594,-11.53125,751.2344,-5.765625Q743.125,0,728.0781,0L696.0781,0L696.0781,-78.75Z" />
<path
android:fillColor="#000000"
android:pathData="M802.34375,0L802.34375,-10.765625Q815.1406,-12.734375,819.0781,-21.59375Q823.8594,-34.03125,823.8594,-65.890625L823.8594,-78.75L877.09375,-78.75L877.09375,0L864.15625,0L864.15625,-68.421875L836.7969,-68.421875L836.7969,-60.609375Q836.7969,-30.234375,830.6094,-16.59375Q824,-2.046875,802.34375,0Z" />
<path
android:fillColor="#000000"
android:pathData="M934.09375,-69.6875Q923.6875,-69.6875,917.6406,-61.5625Q911.59375,-53.4375,911.59375,-39.3125Q911.59375,-25.171875,917.59375,-17.046875Q923.6094,-8.9375,934.09375,-8.9375Q944.4219,-8.9375,950.46875,-17.09375Q956.5156,-25.25,956.5156,-39.3125Q956.5156,-53.296875,950.46875,-61.484375Q944.4219,-69.6875,934.09375,-69.6875ZM934.09375,-80.65625Q950.96875,-80.65625,960.59375,-69.6875Q970.2344,-58.71875,970.2344,-39.3125Q970.2344,-19.96875,960.59375,-8.953125Q950.96875,2.046875,934.09375,2.046875Q917.1406,2.046875,907.5469,-8.953125Q897.9531,-19.96875,897.9531,-39.3125Q897.9531,-58.71875,907.5469,-69.6875Q917.1406,-80.65625,934.09375,-80.65625Z" />
</group> </group>
</group> </group>
</group> </group>
@@ -4,106 +4,118 @@
android:height="108dp" android:height="108dp"
android:viewportWidth="471" android:viewportWidth="471"
android:viewportHeight="458"> android:viewportHeight="458">
<group android:scaleX="0.6670213" <group
android:scaleX="0.6670213"
android:scaleY="0.64861095" android:scaleY="0.64861095"
android:translateX="78.41649" android:translateX="78.41649"
android:translateY="69.15344"> android:translateY="69.15344">
<path <path
android:pathData="M197.58,203.61C170.88,160.97 122.56,149.44 92.05,188.63C74.25,212.83 70.43,237.04 45,250.87C31.02,258.93 33.56,276.22 50.09,281.99C84.42,294.66 140.36,278.53 168.34,250.87C186.14,233.58 195.04,217.44 197.58,203.61Z"
android:strokeLineJoin="round"
android:strokeWidth="7"
android:fillColor="#FFE1D8" android:fillColor="#FFE1D8"
android:pathData="M197.58,203.61C170.88,160.97 122.56,149.44 92.05,188.63C74.25,212.83 70.43,237.04 45,250.87C31.02,258.93 33.56,276.22 50.09,281.99C84.42,294.66 140.36,278.53 168.34,250.87C186.14,233.58 195.04,217.44 197.58,203.61Z"
android:strokeWidth="7"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"/> android:strokeLineCap="round"
<path android:strokeLineJoin="round" />
android:pathData="M155.94,188.24C126.64,181.34 101.52,196.53 84.78,225.53C73.62,243.48 62.45,258.67 49.89,268.34C76.41,276.63 122.45,268.34 150.36,240.72C167.1,224.15 174.08,204.82 155.94,188.24Z"> <path android:pathData="M155.94,188.24C126.64,181.34 101.52,196.53 84.78,225.53C73.62,243.48 62.45,258.67 49.89,268.34C76.41,276.63 122.45,268.34 150.36,240.72C167.1,224.15 174.08,204.82 155.94,188.24Z">
<aapt:attr name="android:fillColor"> <aapt:attr name="android:fillColor">
<gradient <gradient
android:startX="91.76"
android:startY="174.43"
android:endX="161.85" android:endX="161.85"
android:endY="291.08" android:endY="291.08"
android:startX="91.76"
android:startY="174.43"
android:type="linear"> android:type="linear">
<item android:offset="0" android:color="#FFF8B3AD"/> <item
<item android:offset="1" android:color="#FFF2A099"/> android:color="#FFF8B3AD"
android:offset="0" />
<item
android:color="#FFF2A099"
android:offset="1" />
</gradient> </gradient>
</aapt:attr> </aapt:attr>
</path> </path>
<path <path
android:pathData="M273.42,203.61C300.12,160.97 348.44,149.44 378.95,188.63C396.75,212.83 400.57,237.04 426,250.87C439.98,258.93 437.44,276.22 420.91,281.99C386.58,294.66 330.64,278.53 302.66,250.87C284.86,233.58 275.96,217.44 273.42,203.61Z"
android:strokeLineJoin="round"
android:strokeWidth="7"
android:fillColor="#FFE1D8" android:fillColor="#FFE1D8"
android:pathData="M273.42,203.61C300.12,160.97 348.44,149.44 378.95,188.63C396.75,212.83 400.57,237.04 426,250.87C439.98,258.93 437.44,276.22 420.91,281.99C386.58,294.66 330.64,278.53 302.66,250.87C284.86,233.58 275.96,217.44 273.42,203.61Z"
android:strokeWidth="7"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"/> android:strokeLineCap="round"
android:strokeLineJoin="round" />
<path <path
android:pathData="M313.06,188.24C342.36,181.34 367.48,196.53 384.23,225.53C395.39,243.48 406.55,258.67 419.11,268.34C392.6,276.63 346.55,268.34 318.64,240.72C301.9,224.15 294.92,204.82 313.06,188.24Z" android:fillColor="#F2AAA3"
android:fillColor="#F2AAA3"/> android:pathData="M313.06,188.24C342.36,181.34 367.48,196.53 384.23,225.53C395.39,243.48 406.55,258.67 419.11,268.34C392.6,276.63 346.55,268.34 318.64,240.72C301.9,224.15 294.92,204.82 313.06,188.24Z" />
<path <path
android:pathData="M149.68,219.53C149.68,174.25 187.7,150.67 235.5,150.67C283.3,150.67 321.32,174.25 321.32,219.53V258.2C321.32,313.85 281.13,340.26 235.5,340.26C189.88,340.26 149.68,313.85 149.68,258.2V219.53Z" android:pathData="M149.68,219.53C149.68,174.25 187.7,150.67 235.5,150.67C283.3,150.67 321.32,174.25 321.32,219.53V258.2C321.32,313.85 281.13,340.26 235.5,340.26C189.88,340.26 149.68,313.85 149.68,258.2V219.53Z"
android:strokeLineJoin="round"
android:strokeWidth="7" android:strokeWidth="7"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"> android:strokeLineCap="round"
android:strokeLineJoin="round">
<aapt:attr name="android:fillColor"> <aapt:attr name="android:fillColor">
<gradient <gradient
android:centerX="235.5" android:centerX="235.5"
android:centerY="210.09" android:centerY="210.09"
android:gradientRadius="124.5" android:gradientRadius="124.5"
android:type="radial"> android:type="radial">
<item android:offset="0" android:color="#FFFFEFE8"/> <item
<item android:offset="1" android:color="#FFFFD8CE"/> android:color="#FFFFEFE8"
android:offset="0" />
<item
android:color="#FFFFD8CE"
android:offset="1" />
</gradient> </gradient>
</aapt:attr> </aapt:attr>
</path> </path>
<path <path
android:pathData="M197.96,203.74C203.68,203.74 208.32,199.23 208.32,193.67C208.32,188.11 203.68,183.6 197.96,183.6C192.24,183.6 187.6,188.11 187.6,193.67C187.6,199.23 192.24,203.74 197.96,203.74Z" android:fillColor="#5A4844"
android:fillColor="#5A4844"/> android:pathData="M197.96,203.74C203.68,203.74 208.32,199.23 208.32,193.67C208.32,188.11 203.68,183.6 197.96,183.6C192.24,183.6 187.6,188.11 187.6,193.67C187.6,199.23 192.24,203.74 197.96,203.74Z" />
<path <path
android:pathData="M270.8,203.74C276.52,203.74 281.16,199.23 281.16,193.67C281.16,188.11 276.52,183.6 270.8,183.6C265.08,183.6 260.45,188.11 260.45,193.67C260.45,199.23 265.08,203.74 270.8,203.74Z" android:fillColor="#5A4844"
android:fillColor="#5A4844"/> android:pathData="M270.8,203.74C276.52,203.74 281.16,199.23 281.16,193.67C281.16,188.11 276.52,183.6 270.8,183.6C265.08,183.6 260.45,188.11 260.45,193.67C260.45,199.23 265.08,203.74 270.8,203.74Z" />
<path <path
android:pathData="M237.5,318.3C278.28,318.3 311.34,292.62 311.34,260.93C311.34,229.24 278.28,203.56 237.5,203.56C196.71,203.56 163.65,229.24 163.65,260.93C163.65,292.62 196.71,318.3 237.5,318.3Z" android:pathData="M237.5,318.3C278.28,318.3 311.34,292.62 311.34,260.93C311.34,229.24 278.28,203.56 237.5,203.56C196.71,203.56 163.65,229.24 163.65,260.93C163.65,292.62 196.71,318.3 237.5,318.3Z"
android:strokeLineJoin="round"
android:strokeWidth="5" android:strokeWidth="5"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"> android:strokeLineCap="round"
android:strokeLineJoin="round">
<aapt:attr name="android:fillColor"> <aapt:attr name="android:fillColor">
<gradient <gradient
android:centerX="237.5" android:centerX="237.5"
android:centerY="242.68" android:centerY="242.68"
android:gradientRadius="88.67" android:gradientRadius="88.67"
android:type="radial"> android:type="radial">
<item android:offset="0" android:color="#FFFFC4C1"/> <item
<item android:offset="1" android:color="#FFF6A5A5"/> android:color="#FFFFC4C1"
android:offset="0" />
<item
android:color="#FFF6A5A5"
android:offset="1" />
</gradient> </gradient>
</aapt:attr> </aapt:attr>
</path> </path>
<path <path
android:pathData="M204.07,286.38C218.67,286.38 230.51,274.98 230.51,260.93C230.51,246.88 218.67,235.49 204.07,235.49C189.46,235.49 177.62,246.88 177.62,260.93C177.62,274.98 189.46,286.38 204.07,286.38Z" android:fillColor="#4E403D"
android:fillColor="#4E403D"/> android:pathData="M204.07,286.38C218.67,286.38 230.51,274.98 230.51,260.93C230.51,246.88 218.67,235.49 204.07,235.49C189.46,235.49 177.62,246.88 177.62,260.93C177.62,274.98 189.46,286.38 204.07,286.38Z" />
<path <path
android:pathData="M269.93,286.38C284.53,286.38 296.37,274.98 296.37,260.93C296.37,246.88 284.53,235.49 269.93,235.49C255.32,235.49 243.48,246.88 243.48,260.93C243.48,274.98 255.32,286.38 269.93,286.38Z" android:fillColor="#4E403D"
android:fillColor="#4E403D"/> android:pathData="M269.93,286.38C284.53,286.38 296.37,274.98 296.37,260.93C296.37,246.88 284.53,235.49 269.93,235.49C255.32,235.49 243.48,246.88 243.48,260.93C243.48,274.98 255.32,286.38 269.93,286.38Z" />
<path <path
android:pathData="M278.41,274.97C275.1,274.97 272.42,272.29 272.42,268.98V253.02C272.42,249.71 275.1,247.03 278.41,247.03C281.72,247.03 284.4,249.71 284.4,253.02V268.98C284.4,272.29 281.72,274.97 278.41,274.97ZM262.44,274.97C259.14,274.97 256.46,272.29 256.46,268.98V253.02C256.46,249.71 259.14,247.03 262.44,247.03C265.75,247.03 268.43,249.71 268.43,253.02V268.98C268.43,272.29 265.75,274.97 262.44,274.97ZM276.41,268.98C276.41,270.08 277.31,270.98 278.41,270.98C279.51,270.98 280.4,270.08 280.4,268.98V253.02C280.4,251.91 279.51,251.02 278.41,251.02C277.31,251.02 276.41,251.91 276.41,253.02V268.98ZM260.45,268.98C260.45,270.08 261.34,270.98 262.44,270.98C263.55,270.98 264.44,270.08 264.44,268.98V253.02C264.44,251.91 263.55,251.02 262.44,251.02C261.34,251.02 260.45,251.91 260.45,253.02V268.98Z" android:fillColor="#FFD9D0"
android:fillColor="#FFD9D0"/> android:pathData="M278.41,274.97C275.1,274.97 272.42,272.29 272.42,268.98V253.02C272.42,249.71 275.1,247.03 278.41,247.03C281.72,247.03 284.4,249.71 284.4,253.02V268.98C284.4,272.29 281.72,274.97 278.41,274.97ZM262.44,274.97C259.14,274.97 256.46,272.29 256.46,268.98V253.02C256.46,249.71 259.14,247.03 262.44,247.03C265.75,247.03 268.43,249.71 268.43,253.02V268.98C268.43,272.29 265.75,274.97 262.44,274.97ZM276.41,268.98C276.41,270.08 277.31,270.98 278.41,270.98C279.51,270.98 280.4,270.08 280.4,268.98V253.02C280.4,251.91 279.51,251.02 278.41,251.02C277.31,251.02 276.41,251.91 276.41,253.02V268.98ZM260.45,268.98C260.45,270.08 261.34,270.98 262.44,270.98C263.55,270.98 264.44,270.08 264.44,268.98V253.02C264.44,251.91 263.55,251.02 262.44,251.02C261.34,251.02 260.45,251.91 260.45,253.02V268.98Z" />
<path <path
android:pathData="M198.66,276.05C197.33,276.9 195.59,275.95 195.59,274.37V248.63C195.59,247.05 197.33,246.1 198.66,246.95L218.88,259.81C220.11,260.6 220.11,262.4 218.88,263.19L198.66,276.05ZM200.3,265.75C200.3,267.33 202.05,268.29 203.38,267.44L210.04,263.19C211.27,262.4 211.27,260.6 210.04,259.81L203.38,255.56C202.05,254.71 200.3,255.67 200.3,257.25V265.75Z" android:fillColor="#FFDAD0"
android:fillColor="#FFDAD0"/> android:pathData="M198.66,276.05C197.33,276.9 195.59,275.95 195.59,274.37V248.63C195.59,247.05 197.33,246.1 198.66,246.95L218.88,259.81C220.11,260.6 220.11,262.4 218.88,263.19L198.66,276.05ZM200.3,265.75C200.3,267.33 202.05,268.29 203.38,267.44L210.04,263.19C211.27,262.4 211.27,260.6 210.04,259.81L203.38,255.56C202.05,254.71 200.3,255.67 200.3,257.25V265.75Z" />
<path <path
android:fillColor="#00000000"
android:pathData="M150,218.85C150,173.58 188.02,150 235.82,150C283.61,150 321.64,173.58 321.64,218.85V257.53C321.64,313.18 281.44,339.59 235.82,339.59C190.19,339.59 150,313.18 150,257.53V218.85Z" android:pathData="M150,218.85C150,173.58 188.02,150 235.82,150C283.61,150 321.64,173.58 321.64,218.85V257.53C321.64,313.18 281.44,339.59 235.82,339.59C190.19,339.59 150,313.18 150,257.53V218.85Z"
android:strokeLineJoin="round"
android:strokeWidth="7" android:strokeWidth="7"
android:fillColor="#00000000"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"/> android:strokeLineCap="round"
android:strokeLineJoin="round" />
<path <path
android:pathData="M237.84,317.75C278.63,317.75 311.69,292.06 311.69,260.37C311.69,228.69 278.63,203 237.84,203C197.06,203 164,228.69 164,260.37C164,292.06 197.06,317.75 237.84,317.75Z"
android:strokeLineJoin="round"
android:strokeWidth="5"
android:fillColor="#00000000" android:fillColor="#00000000"
android:pathData="M237.84,317.75C278.63,317.75 311.69,292.06 311.69,260.37C311.69,228.69 278.63,203 237.84,203C197.06,203 164,228.69 164,260.37C164,292.06 197.06,317.75 237.84,317.75Z"
android:strokeWidth="5"
android:strokeColor="#7C5A50" android:strokeColor="#7C5A50"
android:strokeLineCap="round"/> android:strokeLineCap="round"
android:strokeLineJoin="round" />
</group> </group>
</vector> </vector>
@@ -1,4 +1,3 @@
package ru.shadowsparky.vbox.shared.data package ru.shadowsparky.vbox.shared.data
import app.cash.sqldelight.Query import app.cash.sqldelight.Query
@@ -78,12 +78,14 @@ class OfflineDownloader(private val context: Context) {
} }
}.getOrDefault(OfflineState.Error("File not found")) }.getOrDefault(OfflineState.Error("File not found"))
} }
DownloadManager.STATUS_FAILED -> { DownloadManager.STATUS_FAILED -> {
val reason = cursor.getInt( val reason = cursor.getInt(
cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON) cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON)
) )
OfflineState.Error("Download failed: reason=$reason") OfflineState.Error("Download failed: reason=$reason")
} }
else -> OfflineState.Error("Unknown status") else -> OfflineState.Error("Unknown status")
} }
} }
@@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="960" android:viewportWidth="960"
android:viewportHeight="960" android:viewportHeight="960">
android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="#fff" android:fillColor="#fff"
android:pathData="M400,720L400,640L560,640L560,720L400,720ZM240,520L240,440L720,440L720,520L240,520ZM120,320L120,240L840,240L840,320L120,320Z" /> android:pathData="M400,720L400,640L560,640L560,720L400,720ZM240,520L240,440L720,440L720,520L240,520ZM120,320L120,240L840,240L840,320L120,320Z" />
@@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="960" android:viewportWidth="960"
android:viewportHeight="960" android:viewportHeight="960">
android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="#fff" android:fillColor="#fff"
android:pathData="M680,880Q630,880 595,845Q560,810 560,760Q560,754 563,732L282,568Q266,583 245,591.5Q224,600 200,600Q150,600 115,565Q80,530 80,480Q80,430 115,395Q150,360 200,360Q224,360 245,368.5Q266,377 282,392L563,228Q561,221 560.5,214.5Q560,208 560,200Q560,150 595,115Q630,80 680,80Q730,80 765,115Q800,150 800,200Q800,250 765,285Q730,320 680,320Q656,320 635,311.5Q614,303 598,288L317,452Q319,459 319.5,465.5Q320,472 320,480Q320,488 319.5,494.5Q319,501 317,508L598,672Q614,657 635,648.5Q656,640 680,640Q730,640 765,675Q800,710 800,760Q800,810 765,845Q730,880 680,880ZM680,800Q697,800 708.5,788.5Q720,777 720,760Q720,743 708.5,731.5Q697,720 680,720Q663,720 651.5,731.5Q640,743 640,760Q640,777 651.5,788.5Q663,800 680,800ZM200,520Q217,520 228.5,508.5Q240,497 240,480Q240,463 228.5,451.5Q217,440 200,440Q183,440 171.5,451.5Q160,463 160,480Q160,497 171.5,508.5Q183,520 200,520ZM708.5,228.5Q720,217 720,200Q720,183 708.5,171.5Q697,160 680,160Q663,160 651.5,171.5Q640,183 640,200Q640,217 651.5,228.5Q663,240 680,240Q697,240 708.5,228.5ZM680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760ZM200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480ZM680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Z" /> android:pathData="M680,880Q630,880 595,845Q560,810 560,760Q560,754 563,732L282,568Q266,583 245,591.5Q224,600 200,600Q150,600 115,565Q80,530 80,480Q80,430 115,395Q150,360 200,360Q224,360 245,368.5Q266,377 282,392L563,228Q561,221 560.5,214.5Q560,208 560,200Q560,150 595,115Q630,80 680,80Q730,80 765,115Q800,150 800,200Q800,250 765,285Q730,320 680,320Q656,320 635,311.5Q614,303 598,288L317,452Q319,459 319.5,465.5Q320,472 320,480Q320,488 319.5,494.5Q319,501 317,508L598,672Q614,657 635,648.5Q656,640 680,640Q730,640 765,675Q800,710 800,760Q800,810 765,845Q730,880 680,880ZM680,800Q697,800 708.5,788.5Q720,777 720,760Q720,743 708.5,731.5Q697,720 680,720Q663,720 651.5,731.5Q640,743 640,760Q640,777 651.5,788.5Q663,800 680,800ZM200,520Q217,520 228.5,508.5Q240,497 240,480Q240,463 228.5,451.5Q217,440 200,440Q183,440 171.5,451.5Q160,463 160,480Q160,497 171.5,508.5Q183,520 200,520ZM708.5,228.5Q720,217 720,200Q720,183 708.5,171.5Q697,160 680,160Q663,160 651.5,171.5Q640,183 640,200Q640,217 651.5,228.5Q663,240 680,240Q697,240 708.5,228.5ZM680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760Q680,760 680,760ZM200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480Q200,480 200,480ZM680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Q680,200 680,200Z" />
@@ -62,7 +62,8 @@ class FallbackVideoApi(
return json.decodeFromString(value) return json.decodeFromString(value)
} }
private suspend inline fun <reified T> writeByKey(key: String, value: T) = withContext(dispatcherProvider.io) { private suspend inline fun <reified T> writeByKey(key: String, value: T) =
withContext(dispatcherProvider.io) {
getCache().insert( getCache().insert(
key, key,
json.encodeToString(value) json.encodeToString(value)
@@ -24,7 +24,8 @@ class SqlRecentlyWatchedRepository(
private val dispatcherProvider: DispatcherProvider private val dispatcherProvider: DispatcherProvider
) : RecentlyWatchedRepository { ) : RecentlyWatchedRepository {
override suspend fun write(info: RecentlyWatchedInfo): Unit = withContext(dispatcherProvider.io) { override suspend fun write(info: RecentlyWatchedInfo): Unit =
withContext(dispatcherProvider.io) {
dbProvider.get().recentlyWatchedQueries.insertRecentlyWatched( dbProvider.get().recentlyWatchedQueries.insertRecentlyWatched(
info.movieId, info.movieId,
info.episode ?: UNKNOWN, info.episode ?: UNKNOWN,
@@ -32,7 +33,8 @@ class SqlRecentlyWatchedRepository(
) )
} }
override suspend fun remove(info: RecentlyWatchedInfo): Unit = withContext(dispatcherProvider.io) { override suspend fun remove(info: RecentlyWatchedInfo): Unit =
withContext(dispatcherProvider.io) {
dbProvider.get().recentlyWatchedQueries.deleteRwByIds( dbProvider.get().recentlyWatchedQueries.deleteRwByIds(
info.movieId, info.movieId,
info.episode ?: UNKNOWN, info.episode ?: UNKNOWN,
@@ -31,7 +31,10 @@ class SyncClientServerRecentlyWatchedRepository(
private val pendingOperationSynchronizer: PendingOperationSynchronizer private val pendingOperationSynchronizer: PendingOperationSynchronizer
) : RecentlyWatchedRepository { ) : RecentlyWatchedRepository {
override fun queryRecentlyWatched(movieId: Long, seasonId: Long?): Flow<List<RecentlyWatchedInfo>> { override fun queryRecentlyWatched(
movieId: Long,
seasonId: Long?
): Flow<List<RecentlyWatchedInfo>> {
return authTokenCache.queryFlow( return authTokenCache.queryFlow(
remote.queryRecentlyWatched(movieId, seasonId), remote.queryRecentlyWatched(movieId, seasonId),
local.queryRecentlyWatched(movieId, seasonId) local.queryRecentlyWatched(movieId, seasonId)
@@ -49,7 +49,8 @@ class SqlSearchRepository(
getQueries().deleteAll() getQueries().deleteAll()
} }
override suspend fun deleteFromSearch(query: String): Unit = withContext(dispatcherProvider.io) { override suspend fun deleteFromSearch(query: String): Unit =
withContext(dispatcherProvider.io) {
getQueries().deleteSearchInfo(query) getQueries().deleteSearchInfo(query)
} }
@@ -28,7 +28,8 @@ class SqlPendingOperationRepository(
getQueries().deleteOperation(id) getQueries().deleteOperation(id)
} }
override suspend fun query(type: AggregateType): List<OperationInfo> = withContext(dispatcherProvider.io) { override suspend fun query(type: AggregateType): List<OperationInfo> =
withContext(dispatcherProvider.io) {
val records = getQueries().getOperationsByAggregate(type.name).awaitAsList() val records = getQueries().getOperationsByAggregate(type.name).awaitAsList()
records.map { record -> records.map { record ->
OperationInfo( OperationInfo(
@@ -40,7 +41,8 @@ class SqlPendingOperationRepository(
} }
} }
override suspend fun insert(operationInfo: OperationInfo): Unit = withContext(dispatcherProvider.io) { override suspend fun insert(operationInfo: OperationInfo): Unit =
withContext(dispatcherProvider.io) {
val payloadString = json.encodeToString(operationInfo.payload) val payloadString = json.encodeToString(operationInfo.payload)
getQueries().insertOperation( getQueries().insertOperation(
aggregateType = operationInfo.type.name, aggregateType = operationInfo.type.name,
@@ -26,16 +26,20 @@ class RecentlyWatchedSyncStrategy(
val info = json.decodeFromJsonElement<RecentlyWatchedInfo>(payload) val info = json.decodeFromJsonElement<RecentlyWatchedInfo>(payload)
remote.write(info) remote.write(info)
} }
SyncClientServerRecentlyWatchedRepository.ACTION_REMOVE -> { SyncClientServerRecentlyWatchedRepository.ACTION_REMOVE -> {
val info = json.decodeFromJsonElement<RecentlyWatchedInfo>(payload) val info = json.decodeFromJsonElement<RecentlyWatchedInfo>(payload)
remote.remove(info) remote.remove(info)
} }
SyncClientServerRecentlyWatchedRepository.ACTION_WRITE_ALL -> { SyncClientServerRecentlyWatchedRepository.ACTION_WRITE_ALL -> {
val payloadObj = payload.jsonObject val payloadObj = payload.jsonObject
val listElement = payloadObj[SyncClientServerRecentlyWatchedRepository.LIST] ?: error("Missing list key") val listElement = payloadObj[SyncClientServerRecentlyWatchedRepository.LIST]
?: error("Missing list key")
val list = json.decodeFromJsonElement<List<RecentlyWatchedInfo>>(listElement) val list = json.decodeFromJsonElement<List<RecentlyWatchedInfo>>(listElement)
remote.writeAll(list) remote.writeAll(list)
} }
else -> error("Unknown action type: $actionType") else -> error("Unknown action type: $actionType")
} }
} }
@@ -29,20 +29,25 @@ class SavedMovieSyncStrategy(
val details = json.decodeFromJsonElement<VideoDetails>(payload) val details = json.decodeFromJsonElement<VideoDetails>(payload)
remote.save(details) remote.save(details)
} }
SyncClientSavedMovieRepository.ACTION_REMOVE -> { SyncClientSavedMovieRepository.ACTION_REMOVE -> {
val id = payload.jsonObject[SyncClientSavedMovieRepository.KEY_ID]?.jsonPrimitive?.long val id =
payload.jsonObject[SyncClientSavedMovieRepository.KEY_ID]?.jsonPrimitive?.long
?: error("Missing ${SyncClientSavedMovieRepository.KEY_ID}") ?: error("Missing ${SyncClientSavedMovieRepository.KEY_ID}")
remote.remove(id) remote.remove(id)
} }
SyncClientSavedMovieRepository.ACTION_SAVE_ALL -> { SyncClientSavedMovieRepository.ACTION_SAVE_ALL -> {
val listElement = payload.jsonObject[SyncClientSavedMovieRepository.KEY_LIST] val listElement = payload.jsonObject[SyncClientSavedMovieRepository.KEY_LIST]
?: error("Missing ${SyncClientSavedMovieRepository.KEY_LIST}") ?: error("Missing ${SyncClientSavedMovieRepository.KEY_LIST}")
val list = json.decodeFromJsonElement<List<VideoDetails>>(listElement) val list = json.decodeFromJsonElement<List<VideoDetails>>(listElement)
remote.saveAll(list) remote.saveAll(list)
} }
SyncClientSavedMovieRepository.ACTION_CLEAR -> { SyncClientSavedMovieRepository.ACTION_CLEAR -> {
remote.clear() remote.clear()
} }
else -> error("Unknown action type: $actionType") else -> error("Unknown action type: $actionType")
} }
} }
@@ -20,15 +20,19 @@ class SearchSyncStrategy(
override suspend fun execute(actionType: String, payload: JsonElement) { override suspend fun execute(actionType: String, payload: JsonElement) {
when (actionType) { when (actionType) {
SyncClientServerSearchRepository.ACTION_ADD -> { SyncClientServerSearchRepository.ACTION_ADD -> {
val query = payload.jsonObject[SyncClientServerSearchRepository.KEY_QUERY]?.jsonPrimitive?.content val query =
payload.jsonObject[SyncClientServerSearchRepository.KEY_QUERY]?.jsonPrimitive?.content
?: error("Missing ${SyncClientServerSearchRepository.KEY_QUERY}") ?: error("Missing ${SyncClientServerSearchRepository.KEY_QUERY}")
remote.addToSearch(query) remote.addToSearch(query)
} }
SyncClientServerSearchRepository.ACTION_DELETE -> { SyncClientServerSearchRepository.ACTION_DELETE -> {
val query = payload.jsonObject[SyncClientServerSearchRepository.KEY_QUERY]?.jsonPrimitive?.content val query =
payload.jsonObject[SyncClientServerSearchRepository.KEY_QUERY]?.jsonPrimitive?.content
?: error("Missing ${SyncClientServerSearchRepository.KEY_QUERY}") ?: error("Missing ${SyncClientServerSearchRepository.KEY_QUERY}")
remote.deleteFromSearch(query) remote.deleteFromSearch(query)
} }
SyncClientServerSearchRepository.ACTION_CLEAR -> remote.clear() SyncClientServerSearchRepository.ACTION_CLEAR -> remote.clear()
else -> error("Unknown action type: $actionType") else -> error("Unknown action type: $actionType")
} }
@@ -3,7 +3,6 @@ package ru.shadowsparky.vbox.shared.data.sync.strategy
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.long
import org.koin.core.annotation.Factory import org.koin.core.annotation.Factory
import org.koin.core.annotation.Named import org.koin.core.annotation.Named
import ru.shadowsparky.vbox.shared.data.tag.SyncUserTagRepository import ru.shadowsparky.vbox.shared.data.tag.SyncUserTagRepository
@@ -26,6 +25,7 @@ class UserTagSyncStrategy(
?: error("Missing ${SyncUserTagRepository.KEY_TAG}") ?: error("Missing ${SyncUserTagRepository.KEY_TAG}")
remote.add(tag) remote.add(tag)
} }
SyncUserTagRepository.ACTION_EDIT -> { SyncUserTagRepository.ACTION_EDIT -> {
val oldTag = payloadObj[SyncUserTagRepository.KEY_OLD_TAG]?.jsonPrimitive?.content val oldTag = payloadObj[SyncUserTagRepository.KEY_OLD_TAG]?.jsonPrimitive?.content
?: error("Missing ${SyncUserTagRepository.KEY_OLD_TAG}") ?: error("Missing ${SyncUserTagRepository.KEY_OLD_TAG}")
@@ -33,11 +33,13 @@ class UserTagSyncStrategy(
?: error("Missing ${SyncUserTagRepository.KEY_NEW_TAG}") ?: error("Missing ${SyncUserTagRepository.KEY_NEW_TAG}")
remote.edit(oldTag, newTag) remote.edit(oldTag, newTag)
} }
SyncUserTagRepository.ACTION_DELETE -> { SyncUserTagRepository.ACTION_DELETE -> {
val oldTag = payloadObj[SyncUserTagRepository.KEY_OLD_TAG]?.jsonPrimitive?.content val oldTag = payloadObj[SyncUserTagRepository.KEY_OLD_TAG]?.jsonPrimitive?.content
?: error("Missing ${SyncUserTagRepository.KEY_OLD_TAG}") ?: error("Missing ${SyncUserTagRepository.KEY_OLD_TAG}")
remote.delete(oldTag) remote.delete(oldTag)
} }
else -> error("Unknown action type: $actionType") else -> error("Unknown action type: $actionType")
} }
} }
@@ -36,7 +36,8 @@ class RemoteUserTagRepository(
private val dispatcherProvider: DispatcherProvider private val dispatcherProvider: DispatcherProvider
) : UserTagRepository { ) : UserTagRepository {
override val userTags: Flow<List<TagInfo>> = userTagListener.event.filterIsInstance<RemoteEvent.OnUserTag>() override val userTags: Flow<List<TagInfo>> =
userTagListener.event.filterIsInstance<RemoteEvent.OnUserTag>()
.map { queryUserTagsSingle() } .map { queryUserTagsSingle() }
.onStart { emit(queryUserTagsSingle()) } .onStart { emit(queryUserTagsSingle()) }
.flowOn(dispatcherProvider.io) .flowOn(dispatcherProvider.io)
@@ -48,13 +48,15 @@ class SyncMovieTagRepository(
queryRemote = { queryRemote = {
val allTags = userTagRemote.userTags.first() val allTags = userTagRemote.userTags.first()
allTags.flatMap { tag -> allTags.flatMap { tag ->
remote.queryMovies(tag.tag).first().map { movieId -> MovieTagLink(movieId, tag.tag) } remote.queryMovies(tag.tag).first()
.map { movieId -> MovieTagLink(movieId, tag.tag) }
} }
}, },
queryLocal = { queryLocal = {
val allTags = userTagLocal.userTags.first() val allTags = userTagLocal.userTags.first()
allTags.flatMap { tag -> allTags.flatMap { tag ->
local.queryMovies(tag.tag).first().map { movieId -> MovieTagLink(movieId, tag.tag) } local.queryMovies(tag.tag).first()
.map { movieId -> MovieTagLink(movieId, tag.tag) }
} }
}, },
writeRemote = { list -> writeRemote = { list ->
@@ -34,7 +34,8 @@ class SavedModule {
serverConfigurationRepository: ServerConfigurationRepository, serverConfigurationRepository: ServerConfigurationRepository,
@Named(EventType.SAVED) eventListener: RemoteEventListener @Named(EventType.SAVED) eventListener: RemoteEventListener
): SavedMovieRepository { ): SavedMovieRepository {
val impl = RemoteSavedMovieRepository(httpClient, serverConfigurationRepository, eventListener) val impl =
RemoteSavedMovieRepository(httpClient, serverConfigurationRepository, eventListener)
return PosterWithoutSuffixSavedMovieRepository(impl) return PosterWithoutSuffixSavedMovieRepository(impl)
} }
} }
@@ -17,7 +17,8 @@ fun <T> TokenStorage.queryFlow(
): Flow<T> { ): Flow<T> {
return flow { return flow {
init() init()
emitAll(if (hasAccount()) { emitAll(
if (hasAccount()) {
active.catch { emitAll(fallback) } active.catch { emitAll(fallback) }
} else { } else {
fallback fallback
@@ -32,7 +32,8 @@ class OfflineVideoInteractor(
seasonId, seasonId,
season.title, season.title,
seasonEntry.value.mapNotNull { episode -> seasonEntry.value.mapNotNull { episode ->
val links = fetchVideoLinks(episode.movieId, seasonId).seasons val links =
fetchVideoLinks(episode.movieId, seasonId).seasons
?.firstOrNull() ?.firstOrNull()
?.episodes?.firstOrNull { it.episode == episode.episodeId } ?.episodes?.firstOrNull { it.episode == episode.episodeId }
if (links == null) { if (links == null) {
@@ -25,7 +25,11 @@ import ru.shadowsparky.vbox.shared.presentation.settings.SettingsContent
fun MainScreen(route: Route, child: Child, rootComponent: RootComponent) { fun MainScreen(route: Route, child: Child, rootComponent: RootComponent) {
when (child) { when (child) {
is Child.SearchChild -> SearchScreen(child.component, route) { rootComponent.nav(it, true) } is Child.SearchChild -> SearchScreen(child.component, route) { rootComponent.nav(it, true) }
is Child.SavedMovieChild -> SavedMovieScreen(child.component, route) { rootComponent.navReplace(it) } is Child.SavedMovieChild -> SavedMovieScreen(
child.component,
route
) { rootComponent.navReplace(it) }
else -> MainScreenInternal(route, child) { rootComponent.navReplace(it) } else -> MainScreenInternal(route, child) { rootComponent.navReplace(it) }
} }
} }
@@ -35,7 +35,11 @@ sealed class Route : ru.shadowsparky.ui.nav.Route() {
class Season(val id: Long, override val routeId: String = RouteIds.SELECT_SEASON) : Route() class Season(val id: Long, override val routeId: String = RouteIds.SELECT_SEASON) : Route()
@Serializable @Serializable
class Episode(val id: Long, val selectedSeasonId: Long, override val routeId: String = RouteIds.SELECT_EPISODE) : Route() class Episode(
val id: Long,
val selectedSeasonId: Long,
override val routeId: String = RouteIds.SELECT_EPISODE
) : Route()
@Serializable @Serializable
class Player( class Player(
@@ -139,6 +139,7 @@ private fun OfflineVideoInfoContent(
} }
} }
} }
@Composable @Composable
private fun MovieHeader( private fun MovieHeader(
title: String, title: String,
@@ -192,7 +192,12 @@ class EpisodeOverviewFactory(
api = api, api = api,
recentlyWatchedRepository = recentlyWatchedRepository, recentlyWatchedRepository = recentlyWatchedRepository,
clipboardManager = clipboardManager, clipboardManager = clipboardManager,
offlineStorage = offlineStorage?.let { SessionOfflineStorage(it, addOfflineVideoUseCase) }, offlineStorage = offlineStorage?.let {
SessionOfflineStorage(
it,
addOfflineVideoUseCase
)
},
dispatcherProvider = dispatcherProvider dispatcherProvider = dispatcherProvider
) )
return Child.EpisodeOverviewChild(comp) return Child.EpisodeOverviewChild(comp)
@@ -282,6 +282,7 @@ private fun RowScope.ShowOfflineIcon(offlineInfo: OfflineVideo?) {
modifier = Modifier.align(Alignment.CenterVertically).size(32.dp) modifier = Modifier.align(Alignment.CenterVertically).size(32.dp)
) )
} }
else -> { else -> {
when (state) { when (state) {
is OfflineState.Available -> Res.drawable.download_done is OfflineState.Available -> Res.drawable.download_done
@@ -68,6 +68,7 @@ class SessionOfflineStorage(
result += operation.item result += operation.item
} }
} }
PendingOperation.Remove -> { PendingOperation.Remove -> {
result.removeAll { it.key() == key } result.removeAll { it.key() == key }
} }
@@ -54,6 +54,7 @@ fun PlayerScreen(component: PlayerComponent) {
) )
} }
} }
is PlayerEvent.Ended -> component.requestNextEpisode() is PlayerEvent.Ended -> component.requestNextEpisode()
is PlayerEvent.Playing -> { is PlayerEvent.Playing -> {
Box(modifier = Modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) {
@@ -68,12 +69,16 @@ fun PlayerScreen(component: PlayerComponent) {
val savedMillis = (effect as? PlayerEffect.SavedTimeFound)?.millis val savedMillis = (effect as? PlayerEffect.SavedTimeFound)?.millis
PlayerActionOverlay( PlayerActionOverlay(
savedMillis != null, savedMillis != null,
text = stringResource(Res.string.start_from, "${savedMillis?.toReadableTime()}") text = stringResource(
Res.string.start_from,
"${savedMillis?.toReadableTime()}"
)
) { component.load(savedMillis) } ) { component.load(savedMillis) }
} }
} }
} }
} }
else -> Loading(Modifier.fillMaxSize()) else -> Loading(Modifier.fillMaxSize())
} }
} }
@@ -137,7 +137,10 @@ fun SearchVideoContent(
}, },
onDeleteRequested = { component.removeFromSearch(it) }) onDeleteRequested = { component.removeFromSearch(it) })
} else { } else {
Box(modifier = Modifier.fillMaxSize().padding(paddingValues), contentAlignment = Alignment.Center) { Box(
modifier = Modifier.fillMaxSize().padding(paddingValues),
contentAlignment = Alignment.Center
) {
Text( Text(
text = stringResource(Res.string.search_empty_now), text = stringResource(Res.string.search_empty_now),
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
@@ -193,7 +193,9 @@ private fun EditTagBottomSheet(
} }
}, },
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
enabled = tagId != null && newTag.isNotEmpty() && newTag != tag.tag && canSave(newTag) enabled = tagId != null && newTag.isNotEmpty() && newTag != tag.tag && canSave(
newTag
)
) { Text(stringResource(Res.string.user_tags_new_tag_save)) } ) { Text(stringResource(Res.string.user_tags_new_tag_save)) }
OutlinedButton( OutlinedButton(
onClick = { onClick = {
@@ -6,7 +6,8 @@ import org.koin.core.annotation.Factory
import ru.shadowsparky.vbox.app.AppDatabase import ru.shadowsparky.vbox.app.AppDatabase
@Factory @Factory
class DesktopDatabaseDriverFactory(private val fileProvider: DesktopFileProvider) : DatabaseDriverFactory { class DesktopDatabaseDriverFactory(private val fileProvider: DesktopFileProvider) :
DatabaseDriverFactory {
override suspend fun createDriver(): SqlDriver { override suspend fun createDriver(): SqlDriver {
val dir = fileProvider.getCacheFileDir() ?: "" val dir = fileProvider.getCacheFileDir() ?: ""
val driver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY + "$dir/videobox.db") val driver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY + "$dir/videobox.db")
@@ -7,7 +7,8 @@ import okio.Path.Companion.toPath
import org.koin.core.annotation.Factory import org.koin.core.annotation.Factory
@Factory @Factory
class DesktopImageLoaderProvider(private val fileProvider: DesktopFileProvider) : ImageLoaderProvider { class DesktopImageLoaderProvider(private val fileProvider: DesktopFileProvider) :
ImageLoaderProvider {
override fun provide(): ImageLoader { override fun provide(): ImageLoader {
return ImageLoader { return ImageLoader {
@@ -26,7 +26,8 @@ class AndroidApplication : Plugin<Project> {
if (propertiesFile.exists()) { if (propertiesFile.exists()) {
val properties = keystorePropertiesProvider.get() val properties = keystorePropertiesProvider.get()
val keystoreFile = rootProject.layout.projectDirectory.file("release.keystore").asFile val keystoreFile =
rootProject.layout.projectDirectory.file("release.keystore").asFile
check(keystoreFile.exists()) { "Unable to load keystore file!" } check(keystoreFile.exists()) { "Unable to load keystore file!" }
storeFile = keystoreFile storeFile = keystoreFile
-4
View File
@@ -1,17 +1,13 @@
kotlin.code.style=official kotlin.code.style=official
android.useAndroidX=true android.useAndroidX=true
org.gradle.jvmargs=-Xms1g -Xmx3584m -XX:+UseParallelGC -Dfile.encoding=UTF-8 org.gradle.jvmargs=-Xms1g -Xmx3584m -XX:+UseParallelGC -Dfile.encoding=UTF-8
org.jetbrains.compose.experimental.jscanvas.enabled=true org.jetbrains.compose.experimental.jscanvas.enabled=true
org.jetbrains.compose.experimental.uikit.enabled=true org.jetbrains.compose.experimental.uikit.enabled=true
android.nonTransitiveRClass=false android.nonTransitiveRClass=false
android.r8.strictFullModeForKeepRules=true android.r8.strictFullModeForKeepRules=true
android.injected.enableStableIds=true android.injected.enableStableIds=true
org.gradle.caching=true org.gradle.caching=true
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.configuration-cache=true org.gradle.configuration-cache=true
# Enabled parallel sync for Gradle 9.4+ # Enabled parallel sync for Gradle 9.4+
org.gradle.tooling.parallel=true org.gradle.tooling.parallel=true
-1
View File
@@ -1,4 +1,3 @@
import com.android.build.api.dsl.LibraryExtension import com.android.build.api.dsl.LibraryExtension
plugins { plugins {
@@ -15,6 +15,10 @@ fun BackButton(doBack: () -> Unit) {
IconButton( IconButton(
onClick = { doBack() }, onClick = { doBack() },
shape = CircleShape, shape = CircleShape,
colors = IconButtonDefaults.iconButtonVibrantColors(containerColor = MaterialTheme.colorScheme.primaryContainer.copy(0.1f)) colors = IconButtonDefaults.iconButtonVibrantColors(
containerColor = MaterialTheme.colorScheme.primaryContainer.copy(
0.1f
)
)
) { Icon(painterResource(Res.drawable.back), contentDescription = null) } ) { Icon(painterResource(Res.drawable.back), contentDescription = null) }
} }
@@ -17,7 +17,8 @@ import androidx.compose.ui.unit.dp
private const val ROUNDED_MAX = 24 private const val ROUNDED_MAX = 24
private const val ROUNDED_MIN = 6 private const val ROUNDED_MIN = 6
@DslMarker private annotation class ExpressiveListDsl @DslMarker
private annotation class ExpressiveListDsl
internal data class ExpressiveNode( internal data class ExpressiveNode(
val key: Any?, val key: Any?,
@@ -79,7 +79,9 @@ class AndroidPlayerController(context: Context) : PlayerController {
} }
} }
init { bindListenerIfNeeded(false) } init {
bindListenerIfNeeded(false)
}
private fun bindListenerIfNeeded(allowFail: Boolean) { private fun bindListenerIfNeeded(allowFail: Boolean) {
try { try {
@@ -153,9 +153,11 @@ fun DefaultControls(
Key.DirectionLeft -> { Key.DirectionLeft -> {
scope.launch { controller.seek(true) } scope.launch { controller.seek(true) }
} }
Key.DirectionRight -> { Key.DirectionRight -> {
scope.launch { controller.seek(false) } scope.launch { controller.seek(false) }
} }
Key.DirectionUp -> focus.play.requestFocus() Key.DirectionUp -> focus.play.requestFocus()
Key.DirectionDown -> focus.audioTrack.requestFocus() Key.DirectionDown -> focus.audioTrack.requestFocus()
else -> return@onPreviewKeyEvent false else -> return@onPreviewKeyEvent false
@@ -307,6 +309,7 @@ private fun BoxScope.CenterControls(
) )
} }
} }
else -> { else -> {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -4,5 +4,7 @@ import org.koin.core.annotation.Factory
@Factory @Factory
class DesktopExternalPlayer : ExternalPlayer { class DesktopExternalPlayer : ExternalPlayer {
override fun play(url: String) { throw NotImplementedError() } override fun play(url: String) {
throw NotImplementedError()
}
} }