Repo created
7
app-ui-catalog/README.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Thunderbird UI Catalog
|
||||
|
||||
Uses [`:core:ui:compose:designsystem`](../core/ui/compose/designsystem/README.md)
|
||||
|
||||
This is a catalog of all the components in the Thunderbird design system.
|
||||
|
||||
It is a work in progress, and will be updated as the design system evolves.
|
||||
41
app-ui-catalog/build.gradle.kts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
plugins {
|
||||
id(ThunderbirdPlugins.App.androidCompose)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
alias(libs.plugins.kotlin.parcelize)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "net.thunderbird.ui.catalog"
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "net.thunderbird.ui.catalog"
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
// Preview build type to render compose without debug features.
|
||||
// This gives a better idea of the real world drawing performance.
|
||||
create("preview") {
|
||||
initWith(getByName("debug"))
|
||||
applicationIdSuffix = ".preview"
|
||||
isDebuggable = false
|
||||
matchingFallbacks += listOf("release")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.core.ui.compose.navigation)
|
||||
|
||||
implementation(projects.core.ui.compose.designsystem)
|
||||
implementation(projects.core.ui.legacy.designsystem)
|
||||
|
||||
implementation(projects.core.ui.compose.theme2.thunderbird)
|
||||
implementation(projects.core.ui.compose.theme2.k9mail)
|
||||
|
||||
implementation(libs.androidx.compose.material3)
|
||||
implementation(libs.androidx.compose.material.icons.extended)
|
||||
|
||||
implementation(libs.kotlinx.datetime)
|
||||
}
|
||||
21
app-ui-catalog/proguard-rules.pro
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import app.k9mail.core.ui.compose.common.annotation.PreviewDevicesWithBackground
|
||||
import app.k9mail.core.ui.compose.designsystem.PreviewWithTheme
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
@PreviewDevicesWithBackground
|
||||
internal fun CatalogContentPreview() {
|
||||
PreviewWithTheme {
|
||||
CatalogAtomContent(
|
||||
pages = persistentListOf(CatalogAtomPage.TYPOGRAPHY, CatalogAtomPage.COLOR),
|
||||
initialPage = CatalogAtomPage.TYPOGRAPHY,
|
||||
onEvent = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom.view
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import app.k9mail.core.ui.compose.common.annotation.PreviewDevices
|
||||
import app.k9mail.core.ui.compose.designsystem.PreviewWithTheme
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true)
|
||||
@PreviewDevices
|
||||
internal fun ColorContentPreview() {
|
||||
PreviewWithTheme {
|
||||
ColorContent(
|
||||
text = "Primary",
|
||||
color = MainTheme.colors.primary,
|
||||
textColor = MainTheme.colors.onPrimary,
|
||||
)
|
||||
}
|
||||
}
|
||||
221
app-ui-catalog/src/debug/res/drawable/ic_app_logo.xml
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="1024dp"
|
||||
android:height="1024dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M866.3,634H493.4C482.5,634 473.6,642.9 473.6,653.8V713.5C473.6,801.4 544.8,872.6 632.6,872.6H839C904.8,872.6 958.3,819.2 958.3,753.3V701.1C958.3,671.2 928.4,634 866.3,634Z"
|
||||
android:fillColor="#008787"/>
|
||||
<path
|
||||
android:pathData="M439.5,260.2L439.6,260.2C466.3,167 582.5,121.5 700.9,121.5C782.7,121.5 856.2,147.4 906.5,188.5C875.3,190.1 845.7,196.2 818.5,206C859.2,221.1 894.2,244.4 920.1,273.2C902.9,270.2 885,268.7 866.8,268.7C864.8,268.7 862.8,268.7 860.9,268.7C907.9,337 935.5,419.7 935.5,508.9C935.5,742.8 745.9,932.4 512,932.4C281.7,932.4 88.5,739.5 88.5,508.9C88.5,472.4 93.3,434.8 102.7,399.5C105.2,392.1 108.6,385 113.2,382.4C118.9,379.2 124.1,388.9 125,392C131.2,415.3 139.5,437.9 149.8,459.5C148.9,411.1 169.6,367.1 198,329C217,303.6 234.5,280 242.6,212.1C243.2,207.6 247.5,204.3 251.9,205.7C313.5,225.9 346.5,328.6 341.4,414.4C375.4,419.3 375.3,383.7 375.3,383.7C364.4,350.2 371.6,288 439.4,260.2L439.5,260.2Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="396.6"
|
||||
android:startY="288.4"
|
||||
android:endX="832.5"
|
||||
android:endY="817.9"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF88CCFC"/>
|
||||
<item android:offset="1" android:color="#FF590DF2"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M921.6,401C931.9,633.9 740.5,834.8 507,834.8C288.4,834.8 109.3,665.8 93.1,451.4C90.2,471.2 88.7,491.4 88.5,512C90.2,741.5 282.9,932.4 512,932.4C745.9,932.4 935.5,742.8 935.5,508.9C935.5,471.6 930.7,435.5 921.6,401Z"
|
||||
android:strokeAlpha="0.9"
|
||||
android:fillAlpha="0.9">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:centerX="234.4"
|
||||
android:centerY="452.7"
|
||||
android:gradientRadius="358.1"
|
||||
android:type="radial">
|
||||
<item android:offset="0.5" android:color="#000B4186"/>
|
||||
<item android:offset="1" android:color="#720B4186"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M502.2,291.3C497.6,283.2 476.5,271.3 467.3,269.2C502.2,157.6 679.7,123.3 788.4,143C833.6,151.3 889.9,175.9 907,188.7C856.7,147.6 783.2,121.7 701.4,121.7C583,121.7 466.7,167.2 440.1,260.4L440,260.4L439.9,260.4C372.1,288.2 364.9,350.5 375.8,383.9C386.2,344 436,295 502.2,291.3Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="587.8"
|
||||
android:startY="332.8"
|
||||
android:endX="442.3"
|
||||
android:endY="231"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#00D13AEF"/>
|
||||
<item android:offset="1" android:color="#E5F9D286"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M624.7,214C529.6,232.7 498.5,238.8 466.7,269.1C502.4,174.4 593.7,155.2 702.5,198.4C672.5,204.6 646.9,209.6 624.7,214Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="307.2"
|
||||
android:startY="473.7"
|
||||
android:endX="616.4"
|
||||
android:endY="164.5"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF450FB0"/>
|
||||
<item android:offset="0.8" android:color="#1E450FB0"/>
|
||||
<item android:offset="1" android:color="#00450FB0"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M111.5,386.6C85.5,493 105.6,618 223.7,723C188.5,684.6 145.6,542.6 240.3,441.2C246.7,434.4 257.6,439.4 258,448.8C265.8,659.5 435.8,788.2 631.9,764.1C571.1,760.7 370.3,690.4 519.7,662.5C597.8,648 720.3,625.2 720.3,515.3C720.3,337.1 582.5,285 499,292.8C441.8,298.1 391,334.4 375.3,383.7C381.3,403.1 357.4,416.8 341.4,414.5C346.5,328.6 313.5,225.9 251.9,205.7C247.5,204.3 243.2,207.6 242.6,212.1C234.5,280 217,303.6 198,329C169.6,367.1 148.9,411.1 149.8,459.5C139.5,437.9 131.2,415.3 125,392C124.3,389.4 120.5,382.1 115.9,381.8C113.4,381.6 112.1,384 111.5,386.6Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:centerX="352.3"
|
||||
android:centerY="739.6"
|
||||
android:gradientRadius="558.7"
|
||||
android:type="radial">
|
||||
<item android:offset="0" android:color="#FF650877"/>
|
||||
<item android:offset="1" android:color="#00340B86"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M467.2,673.3C582.2,766.7 813.5,696.7 813.5,469.6C720.1,611.2 601.2,708.8 467.2,673.3Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="778.1"
|
||||
android:startY="576.8"
|
||||
android:endX="630.1"
|
||||
android:endY="762.5"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#00D647E2"/>
|
||||
<item android:offset="1" android:color="#A3E7BB65"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M240.3,441.2C242.7,438.6 245.8,437.7 248.7,438.1C164,541.5 232.3,723.1 279.3,767.7C281.9,775.1 234.8,736.5 228.3,727.5C192.6,697.2 141.4,547.1 240.3,441.2Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="173.2"
|
||||
android:startY="429.1"
|
||||
android:endX="241.4"
|
||||
android:endY="712.5"
|
||||
android:type="linear">
|
||||
<item android:offset="0.1" android:color="#FFF9BF86"/>
|
||||
<item android:offset="1" android:color="#00D63AEF"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M512,681.9C627,681.9 720.3,605.8 720.3,511.9C720.3,418.1 627,342 512,342C413.9,342 303.7,405.8 303.7,514.4C303.8,682.2 481,778.7 632.1,764.1C620.8,762.8 550,759 502.1,704.9C497.8,700 490.3,691.5 493.7,686C497.1,680.4 506.5,681.9 512,681.9Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="512"
|
||||
android:startY="404.2"
|
||||
android:endX="512"
|
||||
android:endY="762.4"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FFFFFFFF"/>
|
||||
<item android:offset="0.9" android:color="#FFBEE1FE"/>
|
||||
<item android:offset="1" android:color="#FF96CEFD"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M541.2,257C563.5,249.9 561.6,227.9 561.6,227.9C561.6,227.9 550.4,214.8 528.3,222C507.7,228.8 504.4,243.6 504.4,243.6C504.4,243.6 515.7,265 541.2,257Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M512.5,440.5C465.2,423.4 438.7,420.8 391.5,440.5V582C438.7,567 465.3,566.7 512.5,582C564,573.1 589.7,572.9 629,582V440.5C586.8,424 560.8,426.3 512.5,440.5Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="510.3"
|
||||
android:startY="426.7"
|
||||
android:endX="510.3"
|
||||
android:endY="582"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#A3BCE0FD"/>
|
||||
<item android:offset="1" android:color="#00D647E2"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M445,561.3C454.5,561.3 463.8,562.3 472.9,564.4C481.9,566.6 490.9,569.8 499.8,574V454C491.5,449.1 482.7,445.5 473.3,443C464,440.6 454.5,439.4 445,439.4C437.7,439.4 430.4,440.1 423.2,441.5C416,442.9 409.1,445.1 402.4,447.9V568.6C409.5,566.1 416.5,564.3 423.5,563.1C430.5,561.9 437.7,561.3 445,561.3ZM524.2,574C533.1,569.8 542.1,566.6 551.1,564.4C560.2,562.3 569.5,561.3 579,561.3C586.3,561.3 593.5,561.9 600.5,563.1C607.5,564.3 614.5,566.1 621.6,568.6V447.9C614.9,445.1 608,442.9 600.8,441.5C593.6,440.1 586.3,439.4 579,439.4C569.5,439.4 560,440.6 550.7,443C541.3,445.5 532.5,449.1 524.2,454V574ZM512,610C502.3,602.3 491.7,596.3 480.3,592C469,587.8 457.2,585.6 445,585.6C436.5,585.6 428.1,586.7 419.9,589C411.7,591.2 403.8,594.4 396.3,598.4C392,600.7 387.9,600.6 383.9,598.1C380,595.7 378,592.1 378,587.5V440.6C378,438.4 378.6,436.2 379.7,434.2C380.8,432.2 382.5,430.6 384.7,429.6C394,424.8 403.8,421.1 413.9,418.7C424.1,416.2 434.4,415 445,415C456.8,415 468.3,416.5 479.6,419.6C490.8,422.6 501.6,427.2 512,433.3C522.4,427.2 533.2,422.6 544.4,419.6C555.7,416.5 567.2,415 579,415C589.6,415 599.9,416.2 610.1,418.7C620.2,421.1 630,424.8 639.3,429.6C641.5,430.6 643.2,432.2 644.3,434.2C645.4,436.2 646,438.4 646,440.6V587.5C646,592.1 644,595.7 640.1,598.1C636.1,600.6 632,600.7 627.7,598.4C620.2,594.4 612.3,591.2 604.1,589C595.9,586.7 587.5,585.6 579,585.6C566.8,585.6 555,587.8 543.7,592C532.3,596.3 521.7,602.3 512,610Z"
|
||||
android:fillColor="#0768BA"
|
||||
android:fillAlpha="0.3"/>
|
||||
<path
|
||||
android:pathData="M414.5,539.6H428.3L435.3,519.5H466.9L474.2,539.6H487.6L458.1,461H444.1L414.5,539.6ZM439.2,508.2L450.8,475.6H451.4L463,508.2H439.2ZM536.4,486.9V466.2C543.1,463.3 549.9,461.2 556.9,459.8C563.9,458.4 571.3,457.7 579,457.7C584.3,457.7 589.5,458.1 594.5,458.9C599.6,459.7 604.6,460.7 609.5,461.9V481.4C604.6,479.6 599.7,478.2 594.7,477.3C589.7,476.4 584.5,475.9 579,475.9C571.3,475.9 563.9,476.9 556.8,478.8C549.7,480.8 542.9,483.5 536.4,486.9ZM536.4,553.9V533.2C543.1,530.4 549.9,528.2 556.9,526.8C563.9,525.4 571.3,524.7 579,524.7C584.3,524.7 589.5,525.1 594.5,525.9C599.6,526.7 604.6,527.7 609.5,529V548.5C604.6,546.6 599.7,545.3 594.7,544.3C589.7,543.4 584.5,543 579,543C571.3,543 563.9,543.9 556.8,545.7C549.7,547.5 542.9,550.3 536.4,553.9ZM536.4,520.4V499.7C543.1,496.9 549.9,494.7 556.9,493.3C563.9,491.9 571.3,491.2 579,491.2C584.3,491.2 589.5,491.6 594.5,492.4C599.6,493.2 604.6,494.2 609.5,495.4V514.9C604.6,513.1 599.7,511.7 594.7,510.8C589.7,509.9 584.5,509.5 579,509.5C571.3,509.5 563.9,510.4 556.8,512.3C549.7,514.3 542.9,517 536.4,520.4ZM445,561.3C454.5,561.3 463.8,562.3 472.9,564.4C481.9,566.6 490.9,569.8 499.8,574V454C491.5,449.1 482.7,445.5 473.3,443C464,440.6 454.5,439.4 445,439.4C437.7,439.4 430.4,440.1 423.2,441.5C416,442.9 409.1,445.1 402.4,447.9V568.6C409.5,566.1 416.5,564.3 423.5,563.1C430.5,561.9 437.7,561.3 445,561.3ZM524.2,574C533.1,569.8 542.1,566.6 551.1,564.4C560.2,562.3 569.5,561.3 579,561.3C586.3,561.3 593.5,561.9 600.5,563.1C607.5,564.3 614.5,566.1 621.6,568.6V447.9C614.9,445.1 608,442.9 600.8,441.5C593.6,440.1 586.3,439.4 579,439.4C569.5,439.4 560,440.6 550.7,443C541.3,445.5 532.5,449.1 524.2,454V574ZM512,610C502.3,602.3 491.7,596.3 480.3,592C469,587.8 457.2,585.6 445,585.6C436.5,585.6 428.1,586.7 419.9,589C411.7,591.2 403.8,594.4 396.3,598.4C392,600.7 387.9,600.6 383.9,598.1C380,595.7 378,592.1 378,587.5V440.6C378,438.4 378.6,436.2 379.7,434.2C380.8,432.2 382.5,430.6 384.7,429.6C394,424.8 403.8,421.1 413.9,418.7C424.1,416.2 434.4,415 445,415C456.8,415 468.3,416.5 479.6,419.6C490.8,422.6 501.6,427.2 512,433.3C522.4,427.2 533.2,422.6 544.4,419.6C555.7,416.5 567.2,415 579,415C589.6,415 599.9,416.2 610.1,418.7C620.2,421.1 630,424.8 639.3,429.6C641.5,430.6 643.2,432.2 644.3,434.2C645.4,436.2 646,438.4 646,440.6V587.5C646,592.1 644,595.7 640.1,598.1C636.1,600.6 632,600.7 627.7,598.4C620.2,594.4 612.3,591.2 604.1,589C595.9,586.7 587.5,585.6 579,585.6C566.8,585.6 555,587.8 543.7,592C532.3,596.3 521.7,602.3 512,610Z"
|
||||
android:fillAlpha="0.9">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="472"
|
||||
android:startY="430"
|
||||
android:endX="555.5"
|
||||
android:endY="629"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF590DF2"/>
|
||||
<item android:offset="0.5" android:color="#FF1373D9"/>
|
||||
<item android:offset="1" android:color="#FFEF3ACC"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M435.3,517.5H433.8L433.4,518.8L426.8,537.6H417.4L445.5,463H456.7L484.7,537.6H475.6L468.8,518.8L468.3,517.5H466.9H435.3ZM437.3,507.6L436.4,510.2H439.2H463H465.8L464.9,507.6L453.3,475L452.8,473.6H451.4H450.8H449.4L448.9,475L437.3,507.6ZM499,575.9L501.8,577.2V574V454V452.9L500.8,452.3C492.3,447.3 483.3,443.6 473.8,441.1C464.3,438.6 454.7,437.4 445,437.4C437.6,437.4 430.2,438.1 422.8,439.5C415.5,441 408.4,443.2 401.6,446.1L400.4,446.6V447.9V568.6V571.4L403,570.5C410,568 417,566.2 423.9,565C430.8,563.8 437.8,563.3 445,563.3C454.4,563.3 463.5,564.3 472.4,566.4C481.3,568.5 490.1,571.6 499,575.9ZM522.2,574V577.2L525,575.9C533.9,571.6 542.7,568.5 551.6,566.4C560.5,564.3 569.6,563.3 579,563.3C586.2,563.3 593.2,563.8 600.1,565C607,566.2 614,568 621,570.5L623.6,571.4V568.6V447.9V446.6L622.4,446.1C615.6,443.2 608.5,441 601.2,439.5C593.8,438.1 586.4,437.4 579,437.4C569.3,437.4 559.7,438.6 550.2,441.1C540.7,443.6 531.7,447.3 523.2,452.3L522.2,452.9V454V574ZM385.5,431.4L385.6,431.4L385.6,431.4C394.8,426.6 404.4,423 414.4,420.6C424.4,418.2 434.6,417 445,417C456.6,417 467.9,418.5 479,421.5C490.1,424.5 500.8,429 511,435L512,435.6L513,435C523.2,429 533.9,424.5 545,421.5C556.1,418.5 567.4,417 579,417C589.4,417 599.6,418.2 609.6,420.6C619.6,423 629.2,426.6 638.4,431.4L638.4,431.4L638.5,431.4C640.3,432.3 641.7,433.5 642.6,435.2C643.5,436.9 644,438.7 644,440.6V587.5C644,591.4 642.4,594.3 639,596.4C635.7,598.5 632.3,598.6 628.7,596.7C621,592.5 613,589.3 604.6,587C596.3,584.8 587.7,583.6 579,583.6C566.6,583.6 554.6,585.8 543,590.2C531.9,594.3 521.6,600.1 512,607.5C502.4,600.1 492.1,594.3 481,590.2C469.4,585.8 457.4,583.6 445,583.6C436.3,583.6 427.7,584.8 419.4,587C411,589.3 403,592.5 395.3,596.7C391.7,598.6 388.3,598.5 385,596.4C381.6,594.3 380,591.4 380,587.5V440.6C380,438.7 380.5,436.9 381.4,435.2C382.3,433.5 383.7,432.3 385.5,431.4ZM607.5,463.5V478.6C603.4,477.2 599.2,476.1 595,475.3C589.9,474.4 584.6,473.9 579,473.9C571.1,473.9 563.5,474.9 556.2,476.9C550.1,478.6 544.1,480.8 538.4,483.6V467.5C544.6,465 550.9,463.1 557.3,461.7C564.2,460.4 571.4,459.7 579,459.7C584.2,459.7 589.2,460.1 594.2,460.9C598.7,461.6 603.1,462.5 607.5,463.5ZM607.5,530.5V545.6C603.4,544.2 599.2,543.1 595,542.4C589.9,541.4 584.6,541 579,541C571.1,541 563.5,541.9 556.3,543.8C550.1,545.4 544.1,547.6 538.4,550.6V534.6C544.6,532 550.9,530.1 557.3,528.8C564.2,527.4 571.4,526.7 579,526.7C584.2,526.7 589.2,527.1 594.2,527.9C598.7,528.6 603.1,529.5 607.5,530.5ZM607.5,497V512.1C603.4,510.7 599.2,509.6 595,508.9C589.9,507.9 584.6,507.5 579,507.5C571.1,507.5 563.5,508.4 556.2,510.4C550.1,512.1 544.1,514.3 538.4,517.2V501C544.6,498.5 550.9,496.6 557.3,495.3C564.2,493.9 571.4,493.2 579,493.2C584.2,493.2 589.2,493.6 594.2,494.4C598.7,495.1 603.1,496 607.5,497Z"
|
||||
android:strokeAlpha="0.2"
|
||||
android:strokeWidth="4"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#0768BA"/>
|
||||
<path
|
||||
android:pathData="M891,698.4C821.5,837.2 677.9,932.4 512.1,932.4C483.8,932.4 456,929.5 429,924V859.4C429,770.5 497.3,698.4 581.5,698.4H891Z"
|
||||
android:strokeAlpha="0.2"
|
||||
android:fillColor="#000000"
|
||||
android:fillAlpha="0.2"/>
|
||||
<path
|
||||
android:pathData="M866.3,634H493.4C482.5,634 473.6,642.9 473.6,653.8V713.5C473.6,801.4 544.8,872.6 632.6,872.6H839C904.8,872.6 958.3,819.2 958.3,753.3V701.1C958.3,671.2 928.4,634 866.3,634Z"
|
||||
android:strokeAlpha="0.9"
|
||||
android:fillAlpha="0.9">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="856.4"
|
||||
android:startY="862.9"
|
||||
android:endX="727.4"
|
||||
android:endY="740.7"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#7F054096"/>
|
||||
<item android:offset="0.1" android:color="#700F3D9C"/>
|
||||
<item android:offset="0.3" android:color="#3F2F35B1"/>
|
||||
<item android:offset="0.5" android:color="#1C462FBF"/>
|
||||
<item android:offset="0.7" android:color="#07542BC8"/>
|
||||
<item android:offset="0.9" android:color="#00592ACB"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M938.4,720.9H595.6C514.5,720.9 448.7,786.7 448.7,867.8V939.7C448.7,950.7 457.6,959.6 468.6,959.6H811.4C892.5,959.6 958.3,893.8 958.3,812.7V701.1C958.3,712.1 949.4,720.9 938.4,720.9Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="504.7"
|
||||
android:startY="742.8"
|
||||
android:endX="970.6"
|
||||
android:endY="940"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF54FFBD"/>
|
||||
<item android:offset="1" android:color="#FF00DDFF"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M526.1,887H493.1V793.9H526.4C535.7,793.9 543.8,795.8 550.5,799.5C557.3,803.2 562.5,808.5 566.1,815.5C569.8,822.4 571.6,830.7 571.6,840.4C571.6,850.1 569.8,858.4 566.1,865.4C562.5,872.3 557.3,877.7 550.5,881.4C543.7,885.1 535.5,887 526.1,887ZM512.8,870.1H525.3C531.1,870.1 536,869.1 540,867C544,865 547,861.7 549,857.4C551,853 552,847.3 552,840.4C552,833.5 551,827.9 549,823.5C547,819.1 544,815.9 540,813.9C536,811.8 531.1,810.8 525.3,810.8H512.8V870.1Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M586.2,887V793.9H648.9V810.1H605.9V832.3H645.7V848.5H605.9V870.8H649.1V887H586.2Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M664.6,887V793.9H701.9C708.7,793.9 714.4,794.9 719,797C723.6,799 727,801.8 729.3,805.4C731.6,809 732.8,813.1 732.8,817.8C732.8,821.4 732,824.6 730.6,827.4C729.1,830.1 727.1,832.3 724.6,834.1C722.1,835.8 719.2,837 716,837.8V838.7C719.5,838.8 722.8,839.8 725.9,841.7C729,843.5 731.6,846.1 733.5,849.5C735.4,852.8 736.4,856.7 736.4,861.3C736.4,866.2 735.2,870.6 732.7,874.5C730.3,878.3 726.7,881.4 722,883.6C717.2,885.9 711.3,887 704.4,887H664.6ZM684.3,870.9H700.3C705.8,870.9 709.8,869.9 712.3,867.8C714.8,865.7 716.1,862.8 716.1,859.3C716.1,856.7 715.5,854.5 714.2,852.5C713,850.5 711.2,849 708.9,847.9C706.6,846.7 703.9,846.2 700.8,846.2H684.3V870.9ZM684.3,832.9H698.9C701.6,832.9 704,832.4 706,831.5C708.2,830.5 709.8,829.1 711,827.4C712.3,825.6 712.9,823.5 712.9,821C712.9,817.7 711.7,815 709.3,812.9C707,810.8 703.6,809.8 699.2,809.8H684.3V832.9Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M806.7,793.9H826.4V854.4C826.4,861.2 824.8,867.1 821.5,872.2C818.3,877.3 813.8,881.2 808,884.1C802.2,886.9 795.5,888.3 787.8,888.3C780.1,888.3 773.3,886.9 767.5,884.1C761.7,881.2 757.2,877.3 754,872.2C750.8,867.1 749.2,861.2 749.2,854.4V793.9H768.9V852.7C768.9,856.2 769.7,859.4 771.2,862.1C772.8,864.9 775,867.1 777.9,868.6C780.7,870.2 784,871 787.8,871C791.6,871 794.9,870.2 797.8,868.6C800.6,867.1 802.8,864.9 804.4,862.1C805.9,859.4 806.7,856.2 806.7,852.7V793.9Z"
|
||||
android:fillColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M904.3,824C903.7,821.8 902.8,819.8 901.6,818.1C900.5,816.4 899.1,815 897.4,813.8C895.8,812.6 893.9,811.6 891.8,811C889.7,810.4 887.4,810 884.8,810C880.1,810 875.9,811.2 872.3,813.6C868.7,816 865.9,819.4 863.9,823.9C861.9,828.4 860.9,833.9 860.9,840.4C860.9,846.8 861.9,852.4 863.9,856.9C865.8,861.5 868.6,864.9 872.2,867.3C875.8,869.7 880.1,870.9 885,870.9C889.5,870.9 893.3,870.1 896.4,868.5C899.6,866.9 902,864.6 903.7,861.7C905.4,858.8 906.2,855.4 906.2,851.4L910.2,852H886.2V837.2H925.2V848.9C925.2,857.1 923.5,864.1 920,870C916.5,875.8 911.8,880.4 905.7,883.5C899.7,886.7 892.7,888.3 884.9,888.3C876.2,888.3 868.5,886.3 861.9,882.5C855.3,878.6 850.2,873.1 846.5,866C842.8,858.8 841,850.4 841,840.5C841,833 842,826.3 844.2,820.4C846.4,814.4 849.5,809.4 853.5,805.3C857.5,801.2 862.1,798 867.4,795.9C872.6,793.7 878.3,792.6 884.5,792.6C889.8,792.6 894.7,793.4 899.2,795C903.8,796.5 907.8,798.6 911.3,801.4C914.9,804.2 917.8,807.5 920,811.4C922.2,815.2 923.7,819.4 924.3,824H904.3Z"
|
||||
android:fillColor="#000000"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="1024dp"
|
||||
android:height="1024dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M595.6,720.9H938.4C949.4,720.9 958.3,712 958.3,701.1V812.7C958.3,893.8 892.5,959.6 811.4,959.6H468.6C457.6,959.6 448.7,950.7 448.7,939.7V867.8C448.7,786.7 514.5,720.9 595.6,720.9ZM504.6,887H535.5C544.4,887 552,885.3 558.4,881.8C564.8,878.3 569.7,873.3 573.1,866.7C576.5,860.2 578.2,852.4 578.2,843.3C578.2,834.2 576.5,826.4 573.1,819.9C569.7,813.4 564.8,808.4 558.4,805C552.1,801.5 544.6,799.7 535.8,799.7H504.6V887ZM534.8,871.2H523V815.5H534.8C540.3,815.5 544.8,816.5 548.6,818.4C552.3,820.4 555.1,823.4 557,827.5C558.9,831.6 559.8,836.8 559.8,843.3C559.8,849.8 558.9,855.1 557,859.2C555.1,863.3 552.3,866.3 548.5,868.3C544.8,870.2 540.2,871.2 534.8,871.2ZM591.9,799.7V887H650.9V871.8H610.3V850.9H647.7V835.7H610.3V814.9H650.7V799.7H591.9ZM665.4,799.7V887H702.7C709.2,887 714.7,885.9 719.1,883.8C723.6,881.7 727,878.9 729.2,875.3C731.5,871.6 732.7,867.5 732.7,862.9C732.7,858.6 731.8,854.9 730,851.8C728.2,848.7 725.8,846.2 722.9,844.5C720,842.8 716.8,841.8 713.5,841.7V840.8C716.6,840.2 719.3,839 721.6,837.4C724,835.8 725.9,833.6 727.2,831.1C728.6,828.5 729.3,825.5 729.3,822.1C729.3,817.7 728.2,813.9 726,810.5C723.9,807.1 720.7,804.5 716.4,802.6C712.1,800.7 706.7,799.7 700.3,799.7H665.4ZM698.9,871.9H683.8V848.7H699.3C702.2,848.7 704.8,849.3 706.9,850.3C709.1,851.4 710.7,852.8 711.9,854.7C713.1,856.5 713.6,858.6 713.6,861C713.6,864.3 712.5,867 710.1,869C707.8,870.9 704,871.9 698.9,871.9ZM697.5,836.2H683.8V814.6H697.8C701.9,814.6 705.1,815.6 707.3,817.5C709.5,819.5 710.7,822 710.7,825.2C710.7,827.5 710.1,829.4 708.9,831.1C707.8,832.7 706.2,834 704.2,834.9C702.3,835.8 700,836.2 697.5,836.2ZM817.1,799.7H798.6V854.8C798.6,858.2 797.9,861.1 796.4,863.7C794.9,866.3 792.9,868.3 790.2,869.8C787.6,871.3 784.5,872 780.9,872C777.3,872 774.2,871.3 771.5,869.8C768.9,868.3 766.8,866.3 765.3,863.7C763.9,861.1 763.2,858.2 763.2,854.8V799.7H744.7V856.4C744.7,862.8 746.2,868.3 749.2,873.1C752.2,877.9 756.5,881.6 761.9,884.3C767.3,886.9 773.6,888.2 780.9,888.2C788.1,888.2 794.4,886.9 799.8,884.3C805.3,881.6 809.5,877.9 812.5,873.1C815.5,868.3 817.1,862.8 817.1,856.4V799.7ZM887.6,822.4C888.7,824 889.5,825.9 890.1,827.9H908.9C908.3,823.6 906.9,819.7 904.8,816.1C902.7,812.5 900,809.4 896.7,806.8C893.4,804.1 889.6,802.1 885.3,800.7C881.1,799.3 876.5,798.5 871.5,798.5C865.8,798.5 860.4,799.5 855.5,801.6C850.5,803.6 846.2,806.5 842.5,810.4C838.7,814.2 835.8,819 833.8,824.5C831.7,830.1 830.7,836.4 830.7,843.4C830.7,852.7 832.4,860.6 835.9,867.3C839.3,874 844.2,879.1 850.4,882.8C856.5,886.4 863.7,888.2 871.9,888.2C879.2,888.2 885.8,886.7 891.4,883.8C897.1,880.8 901.6,876.5 904.8,871.1C908.1,865.6 909.7,859 909.7,851.3V840.3H873.2V854.2H891.9C891.8,857.7 891,860.7 889.5,863.3C888,866 885.7,868.2 882.7,869.7C879.7,871.1 876.2,871.9 872,871.9C867.4,871.9 863.4,870.8 860,868.5C856.6,866.3 854,863.1 852.2,858.8C850.3,854.5 849.4,849.4 849.4,843.3C849.4,837.2 850.4,832.1 852.2,827.9C854.1,823.6 856.7,820.4 860.1,818.2C863.4,816 867.4,814.9 871.8,814.9C874.2,814.9 876.4,815.2 878.3,815.8C880.3,816.3 882.1,817.2 883.6,818.3C885.2,819.5 886.5,820.8 887.6,822.4Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M440,249.7L440.1,249.7C466.8,156.5 583,111 701.4,111C783.2,111 856.7,136.9 907,178C875.8,179.6 846.2,185.7 819,195.5C859.7,210.7 894.7,233.9 920.6,262.7C903.4,259.7 885.5,258.2 867.3,258.2C865.3,258.2 863.3,258.2 861.4,258.2C908.4,326.5 936,409.2 936,498.4C936,575 915.6,646.9 880,708.9H595.6C573.7,708.9 552.7,713.4 533.7,721.4C522.9,714.2 512.3,705.3 502.6,694.4C498.3,689.5 490.8,681 494.2,675.5C497.1,670.8 504.1,671.1 509.6,671.3L509.6,671.3C510.6,671.4 511.6,671.4 512.5,671.4C627.5,671.4 720.8,595.3 720.8,501.4C720.8,407.6 627.5,331.5 512.5,331.5C465.1,331.5 415,346.4 375.8,374C375.8,373.5 375.8,373.2 375.8,373.2C364.9,339.8 372.1,277.6 439.9,249.7L440,249.7ZM501.4,739.9C394.7,707.3 304.3,623.8 304.2,503.9C304.2,464.4 318.8,430.8 342.1,404C342.1,404 342.1,404 342,404C342,404 341.9,404 341.9,404C347,318.1 314,215.4 252.4,195.2C248,193.8 243.7,197.1 243.1,201.6C235,269.6 217.5,293.1 198.5,318.5C170.1,356.6 149.4,400.6 150.3,449C140,427.4 131.7,404.9 125.5,381.6C124.6,378.4 119.4,368.7 113.7,372C109.1,374.6 105.7,381.7 103.2,389.1C93.8,424.3 89,462 89,498.4C89,703.2 241.3,878.2 436.7,914.9V867.8C436.7,815.3 462.2,768.8 501.4,739.9ZM541.7,246.5C564,239.5 562.1,217.4 562.1,217.4C562.1,217.4 550.9,204.3 528.8,211.6C508.2,218.4 504.9,233.1 504.9,233.1C504.9,233.1 516.2,254.5 541.7,246.5Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M893.8,708.9C904.8,689.2 914.2,668.4 922,646.9C939.1,656.4 950.1,670 955.1,683.7C956.3,687 955.5,691.5 954,695C948.5,708 942.7,708.9 938.4,708.9H893.8ZM911.1,641.8C902.7,665.2 892.3,687.7 880,708.9L809,708.9V635.4L866.3,634C883.8,634 898.7,636.9 911.1,641.8ZM809,720.9V767H957.5C958,762.5 958.3,757.9 958.3,753.3V701.2C958.2,709.3 953.3,716.3 946.3,719.3C943.8,720.4 941.2,720.9 938.4,720.9L887,720.9L809,720.9Z"
|
||||
android:strokeAlpha="0.9"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"
|
||||
android:fillAlpha="0.9"/>
|
||||
<path
|
||||
android:pathData="M595.6,720.9H938.4C949.4,720.9 958.3,712 958.3,701.1V812.7C958.3,893.8 892.5,959.6 811.4,959.6H468.6C457.6,959.6 448.7,950.7 448.7,939.7V867.8C448.7,786.7 514.5,720.9 595.6,720.9ZM504.6,887H535.5C544.4,887 552,885.3 558.4,881.8C564.8,878.3 569.7,873.3 573.1,866.7C576.5,860.2 578.2,852.4 578.2,843.3C578.2,834.2 576.5,826.4 573.1,819.9C569.7,813.4 564.8,808.4 558.4,805C552.1,801.5 544.6,799.7 535.8,799.7H504.6V887ZM534.8,871.2H523V815.5H534.8C540.3,815.5 544.8,816.5 548.6,818.4C552.3,820.4 555.1,823.4 557,827.5C558.9,831.6 559.8,836.8 559.8,843.3C559.8,849.8 558.9,855.1 557,859.2C555.1,863.3 552.3,866.3 548.5,868.3C544.8,870.2 540.2,871.2 534.8,871.2ZM591.9,799.7V887H650.9V871.8H610.3V850.9H647.7V835.7H610.3V814.9H650.7V799.7H591.9ZM665.4,799.7V887H702.7C709.2,887 714.7,885.9 719.1,883.8C723.6,881.7 727,878.9 729.2,875.3C731.5,871.6 732.7,867.5 732.7,862.9C732.7,858.6 731.8,854.9 730,851.8C728.2,848.7 725.8,846.2 722.9,844.5C720,842.8 716.8,841.8 713.5,841.7V840.8C716.6,840.2 719.3,839 721.6,837.4C724,835.8 725.9,833.6 727.2,831.1C728.6,828.5 729.3,825.5 729.3,822.1C729.3,817.7 728.2,813.9 726,810.5C723.9,807.1 720.7,804.5 716.4,802.6C712.1,800.7 706.7,799.7 700.3,799.7H665.4ZM698.9,871.9H683.8V848.7H699.3C702.2,848.7 704.8,849.3 706.9,850.3C709.1,851.4 710.7,852.8 711.9,854.7C713.1,856.5 713.6,858.6 713.6,861C713.6,864.3 712.5,867 710.1,869C707.8,870.9 704,871.9 698.9,871.9ZM697.5,836.2H683.8V814.6H697.8C701.9,814.6 705.1,815.6 707.3,817.5C709.5,819.5 710.7,822 710.7,825.2C710.7,827.5 710.1,829.4 708.9,831.1C707.8,832.7 706.2,834 704.2,834.9C702.3,835.8 700,836.2 697.5,836.2ZM817.1,799.7H798.6V854.8C798.6,858.2 797.9,861.1 796.4,863.7C794.9,866.3 792.9,868.3 790.2,869.8C787.6,871.3 784.5,872 780.9,872C777.3,872 774.2,871.3 771.5,869.8C768.9,868.3 766.8,866.3 765.3,863.7C763.9,861.1 763.2,858.2 763.2,854.8V799.7H744.7V856.4C744.7,862.8 746.2,868.3 749.2,873.1C752.2,877.9 756.5,881.6 761.9,884.3C767.3,886.9 773.6,888.2 780.9,888.2C788.1,888.2 794.4,886.9 799.8,884.3C805.3,881.6 809.5,877.9 812.5,873.1C815.5,868.3 817.1,862.8 817.1,856.4V799.7ZM887.6,822.4C888.7,824 889.5,825.9 890.1,827.9H908.9C908.3,823.6 906.9,819.7 904.8,816.1C902.7,812.5 900,809.4 896.7,806.8C893.4,804.1 889.6,802.1 885.3,800.7C881.1,799.3 876.5,798.5 871.5,798.5C865.8,798.5 860.4,799.5 855.5,801.6C850.5,803.6 846.2,806.5 842.5,810.4C838.7,814.2 835.8,819 833.8,824.5C831.7,830.1 830.7,836.4 830.7,843.4C830.7,852.7 832.4,860.6 835.9,867.3C839.3,874 844.2,879.1 850.4,882.8C856.5,886.4 863.7,888.2 871.9,888.2C879.2,888.2 885.8,886.7 891.4,883.8C897.1,880.8 901.6,876.5 904.8,871.1C908.1,865.6 909.7,859 909.7,851.3V840.3H873.2V854.2H891.9C891.8,857.7 891,860.7 889.5,863.3C888,866 885.7,868.2 882.7,869.7C879.7,871.1 876.2,871.9 872,871.9C867.4,871.9 863.4,870.8 860,868.5C856.6,866.3 854,863.1 852.2,858.8C850.3,854.5 849.4,849.4 849.4,843.3C849.4,837.2 850.4,832.1 852.2,827.9C854.1,823.6 856.7,820.4 860.1,818.2C863.4,816 867.4,814.9 871.8,814.9C874.2,814.9 876.4,815.2 878.3,815.8C880.3,816.3 882.1,817.2 883.6,818.3C885.2,819.5 886.5,820.8 887.6,822.4Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M440,249.7L440.1,249.7C466.8,156.5 583,111 701.4,111C783.2,111 856.7,136.9 907,178C875.8,179.6 846.2,185.7 819,195.5C859.7,210.7 894.7,233.9 920.6,262.7C903.4,259.7 885.5,258.2 867.3,258.2C865.3,258.2 863.3,258.2 861.4,258.2C908.4,326.5 936,409.2 936,498.4C936,575 915.6,646.9 880,708.9H595.6C573.7,708.9 552.7,713.4 533.7,721.4C522.9,714.2 512.3,705.3 502.6,694.4C498.3,689.5 490.8,681 494.2,675.5C497.1,670.8 504.1,671.1 509.6,671.3L509.6,671.3C510.6,671.4 511.6,671.4 512.5,671.4C627.5,671.4 720.8,595.3 720.8,501.4C720.8,407.6 627.5,331.5 512.5,331.5C465.1,331.5 415,346.4 375.8,374C375.8,373.5 375.8,373.2 375.8,373.2C364.9,339.8 372.1,277.6 439.9,249.7L440,249.7ZM501.4,739.9C394.7,707.3 304.3,623.8 304.2,503.9C304.2,464.4 318.8,430.8 342.1,404C342.1,404 342.1,404 342,404C342,404 341.9,404 341.9,404C347,318.1 314,215.4 252.4,195.2C248,193.8 243.7,197.1 243.1,201.6C235,269.6 217.5,293.1 198.5,318.5C170.1,356.6 149.4,400.6 150.3,449C140,427.4 131.7,404.9 125.5,381.6C124.6,378.4 119.4,368.7 113.7,372C109.1,374.6 105.7,381.7 103.2,389.1C93.8,424.3 89,462 89,498.4C89,703.2 241.3,878.2 436.7,914.9V867.8C436.7,815.3 462.2,768.8 501.4,739.9ZM541.7,246.5C564,239.5 562.1,217.4 562.1,217.4C562.1,217.4 550.9,204.3 528.8,211.6C508.2,218.4 504.9,233.1 504.9,233.1C504.9,233.1 516.2,254.5 541.7,246.5Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M893.8,708.9C904.8,689.2 914.2,668.4 922,646.9C939.1,656.4 950.1,670 955.1,683.7C956.3,687 955.5,691.5 954,695C948.5,708 942.7,708.9 938.4,708.9H893.8ZM911.1,641.8C902.7,665.2 892.3,687.7 880,708.9L809,708.9V635.4L866.3,634C883.8,634 898.7,636.9 911.1,641.8ZM809,720.9V767H957.5C958,762.5 958.3,757.9 958.3,753.3V701.2C958.2,709.3 953.3,716.3 946.3,719.3C943.8,720.4 941.2,720.9 938.4,720.9L887,720.9L809,720.9Z"
|
||||
android:strokeAlpha="0.9"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"
|
||||
android:fillAlpha="0.9"/>
|
||||
<path
|
||||
android:pathData="M414.5,543.6H428.3L435.3,523.5H466.9L474.2,543.6H487.6L458.1,465H444.1L414.5,543.6ZM439.2,512.2L450.8,479.6H451.4L463,512.2H439.2ZM536.4,490.9V470.2C543.1,467.3 549.9,465.2 556.9,463.8C563.9,462.4 571.3,461.7 579,461.7C584.3,461.7 589.5,462.1 594.5,462.9C599.6,463.7 604.6,464.7 609.5,465.9V485.4C604.6,483.6 599.7,482.2 594.7,481.3C589.7,480.4 584.5,479.9 579,479.9C571.3,479.9 563.9,480.9 556.8,482.8C549.7,484.8 542.9,487.5 536.4,490.9ZM536.4,557.9V537.2C543.1,534.4 549.9,532.2 556.9,530.8C563.9,529.4 571.3,528.7 579,528.7C584.3,528.7 589.5,529.1 594.5,529.9C599.6,530.7 604.6,531.7 609.5,533V552.5C604.6,550.6 599.7,549.3 594.7,548.3C589.7,547.4 584.5,547 579,547C571.3,547 563.9,547.9 556.8,549.7C549.7,551.5 542.9,554.3 536.4,557.9ZM536.4,524.4V503.7C543.1,500.9 549.9,498.7 556.9,497.3C563.9,495.9 571.3,495.2 579,495.2C584.3,495.2 589.5,495.6 594.5,496.4C599.6,497.2 604.6,498.2 609.5,499.4V518.9C604.6,517.1 599.7,515.7 594.7,514.8C589.7,513.9 584.5,513.5 579,513.5C571.3,513.5 563.9,514.4 556.8,516.3C549.7,518.3 542.9,521 536.4,524.4ZM445,565.3C454.5,565.3 463.8,566.3 472.9,568.4C481.9,570.6 490.9,573.8 499.8,578V458C491.5,453.1 482.7,449.5 473.3,447C464,444.6 454.5,443.4 445,443.4C437.7,443.4 430.4,444.1 423.2,445.5C416,446.9 409.1,449.1 402.4,451.9V572.6C409.5,570.1 416.5,568.3 423.5,567.1C430.5,565.9 437.7,565.3 445,565.3ZM524.2,578C533.1,573.8 542.1,570.6 551.1,568.4C560.2,566.3 569.5,565.3 579,565.3C586.3,565.3 593.5,565.9 600.5,567.1C607.5,568.3 614.5,570.1 621.6,572.6V451.9C614.9,449.1 608,446.9 600.8,445.5C593.6,444.1 586.3,443.4 579,443.4C569.5,443.4 560,444.6 550.7,447C541.3,449.5 532.5,453.1 524.2,458V578ZM512,614C502.3,606.3 491.7,600.3 480.3,596C469,591.8 457.2,589.6 445,589.6C436.5,589.6 428.1,590.7 419.9,593C411.7,595.2 403.8,598.4 396.3,602.4C392,604.7 387.9,604.6 383.9,602.1C380,599.7 378,596.1 378,591.5V444.6C378,442.4 378.6,440.2 379.7,438.2C380.8,436.2 382.5,434.6 384.7,433.6C394,428.8 403.8,425.1 413.9,422.7C424.1,420.2 434.4,419 445,419C456.8,419 468.3,420.5 479.6,423.6C490.8,426.6 501.6,431.2 512,437.3C522.4,431.2 533.2,426.6 544.4,423.6C555.7,420.5 567.2,419 579,419C589.6,419 599.9,420.2 610.1,422.7C620.2,425.1 630,428.8 639.3,433.6C641.5,434.6 643.2,436.2 644.3,438.2C645.4,440.2 646,442.4 646,444.6V591.5C646,596.1 644,599.7 640.1,602.1C636.1,604.6 632,604.7 627.7,602.4C620.2,598.4 612.3,595.2 604.1,593C595.9,590.7 587.5,589.6 579,589.6C566.8,589.6 555,591.8 543.7,596C532.3,600.3 521.7,606.3 512,614Z"
|
||||
android:fillColor="#000000"/>
|
||||
</vector>
|
||||
BIN
app-ui-catalog/src/debug/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
app-ui-catalog/src/debug/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
app-ui-catalog/src/debug/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 8.8 KiB |
BIN
app-ui-catalog/src/debug/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
app-ui-catalog/src/debug/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
29
app-ui-catalog/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:name=".CatalogApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Thunderbird.Splashscreen"
|
||||
>
|
||||
|
||||
<activity
|
||||
android:name=".CatalogActivity"
|
||||
android:exported="true"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package net.thunderbird.ui.catalog
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import net.thunderbird.ui.catalog.ui.CatalogScreen
|
||||
|
||||
class CatalogActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
installSplashScreen()
|
||||
enableEdgeToEdge()
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContent {
|
||||
CatalogScreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package net.thunderbird.ui.catalog
|
||||
|
||||
import android.app.Application
|
||||
import net.thunderbird.ui.catalog.di.catalogUiModule
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.core.context.startKoin
|
||||
|
||||
class CatalogApplication : Application() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
startKoin {
|
||||
allowOverride(false)
|
||||
androidContext(this@CatalogApplication)
|
||||
modules(catalogUiModule)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package net.thunderbird.ui.catalog.di
|
||||
|
||||
import net.thunderbird.ui.catalog.ui.CatalogViewModel
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageViewModel
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.core.module.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val catalogUiModule: Module = module {
|
||||
viewModel { CatalogViewModel() }
|
||||
viewModel { CatalogPageViewModel() }
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package net.thunderbird.ui.catalog.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavOptions
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.drawer.ModalNavigationDrawer
|
||||
import app.k9mail.core.ui.compose.designsystem.template.Scaffold
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.State
|
||||
import net.thunderbird.ui.catalog.ui.common.ThemeTopAppBar
|
||||
import net.thunderbird.ui.catalog.ui.common.drawer.DrawerContent
|
||||
import net.thunderbird.ui.catalog.ui.navigation.CatalogNavHost
|
||||
import net.thunderbird.ui.catalog.ui.navigation.CatalogRoute
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
fun CatalogContent(
|
||||
navController: NavHostController,
|
||||
state: State,
|
||||
onThemeChanged: () -> Unit,
|
||||
onThemeVariantChanged: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
ModalNavigationDrawer(
|
||||
drawerContent = { closeDrawer ->
|
||||
DrawerContent(
|
||||
closeDrawer = closeDrawer,
|
||||
theme = state.theme,
|
||||
themeVariant = state.themeVariant,
|
||||
onThemeChanged = onThemeChanged,
|
||||
onThemeVariantChanged = onThemeVariantChanged,
|
||||
onNavigateToAtoms = {
|
||||
navController.navigate(
|
||||
route = CatalogRoute.Atom,
|
||||
navOptions = NavOptions.Builder()
|
||||
.setLaunchSingleTop(true)
|
||||
.build(),
|
||||
)
|
||||
},
|
||||
onNavigateToMolecules = {
|
||||
navController.navigate(
|
||||
route = CatalogRoute.Molecule,
|
||||
navOptions = NavOptions.Builder()
|
||||
.setLaunchSingleTop(true)
|
||||
.build(),
|
||||
)
|
||||
},
|
||||
onNavigateToOrganisms = {
|
||||
navController.navigate(
|
||||
route = CatalogRoute.Organism,
|
||||
navOptions = NavOptions.Builder()
|
||||
.setLaunchSingleTop(true)
|
||||
.build(),
|
||||
)
|
||||
},
|
||||
onNavigateToTemplates = {
|
||||
navController.navigate(
|
||||
route = CatalogRoute.Template,
|
||||
navOptions = NavOptions.Builder()
|
||||
.setLaunchSingleTop(true)
|
||||
.build(),
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
) { openDrawer ->
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
topBar = {
|
||||
ThemeTopAppBar(
|
||||
onMenuClick = openDrawer,
|
||||
theme = state.theme,
|
||||
themeVariant = state.themeVariant,
|
||||
onThemeClick = onThemeChanged,
|
||||
onThemeVariantClick = onThemeVariantChanged,
|
||||
)
|
||||
},
|
||||
) { paddingValues ->
|
||||
CatalogNavHost(
|
||||
navController = navController,
|
||||
paddingValues = paddingValues,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package net.thunderbird.ui.catalog.ui
|
||||
|
||||
import app.k9mail.core.ui.compose.common.mvi.UnidirectionalViewModel
|
||||
|
||||
interface CatalogContract {
|
||||
|
||||
enum class Theme(
|
||||
val displayName: String,
|
||||
) {
|
||||
THEME_2_K9("K-9 UI"),
|
||||
THEME_2_THUNDERBIRD("Thunderbird UI"),
|
||||
}
|
||||
|
||||
enum class ThemeVariant(
|
||||
val displayName: String,
|
||||
) {
|
||||
LIGHT("Light"),
|
||||
DARK("Dark"),
|
||||
}
|
||||
|
||||
interface ViewModel : UnidirectionalViewModel<State, Event, Nothing>
|
||||
|
||||
data class State(
|
||||
val theme: Theme = Theme.THEME_2_THUNDERBIRD,
|
||||
val themeVariant: ThemeVariant = ThemeVariant.LIGHT,
|
||||
)
|
||||
|
||||
sealed interface Event {
|
||||
data object OnThemeChanged : Event
|
||||
|
||||
data object OnThemeVariantChanged : Event
|
||||
}
|
||||
}
|
||||
|
||||
fun CatalogContract.Theme.next(): CatalogContract.Theme {
|
||||
val themes = CatalogContract.Theme.entries
|
||||
val currentThemeIndex = themes.indexOf(this)
|
||||
val nextThemeIndex = (currentThemeIndex + 1) % themes.size
|
||||
return themes[nextThemeIndex]
|
||||
}
|
||||
|
||||
fun CatalogContract.ThemeVariant.next(): CatalogContract.ThemeVariant {
|
||||
val variants = CatalogContract.ThemeVariant.entries
|
||||
val currentVariantIndex = variants.indexOf(this)
|
||||
val nextVariantIndex = (currentVariantIndex + 1) % variants.size
|
||||
return variants[nextVariantIndex]
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package net.thunderbird.ui.catalog.ui
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import app.k9mail.core.ui.compose.common.mvi.observe
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.Surface
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.Event.OnThemeChanged
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.Event.OnThemeVariantChanged
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.ViewModel
|
||||
import net.thunderbird.ui.catalog.ui.common.theme.ThemeSwitch
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@Composable
|
||||
fun CatalogScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: ViewModel = koinViewModel<CatalogViewModel>(),
|
||||
) {
|
||||
val (state, dispatch) = viewModel.observe(handleEffect = {})
|
||||
val navController = rememberNavController()
|
||||
|
||||
ThemeSwitch(
|
||||
theme = state.value.theme,
|
||||
themeVariant = state.value.themeVariant,
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.safeDrawingPadding()
|
||||
.then(modifier),
|
||||
) {
|
||||
CatalogContent(
|
||||
navController = navController,
|
||||
state = state.value,
|
||||
onThemeChanged = { dispatch(OnThemeChanged) },
|
||||
onThemeVariantChanged = { dispatch(OnThemeVariantChanged) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package net.thunderbird.ui.catalog.ui
|
||||
|
||||
import app.k9mail.core.ui.compose.common.mvi.BaseViewModel
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.Event
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.Event.OnThemeChanged
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.Event.OnThemeVariantChanged
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.State
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.ViewModel
|
||||
|
||||
class CatalogViewModel(
|
||||
initialState: State = State(),
|
||||
) : BaseViewModel<State, Event, Nothing>(initialState), ViewModel {
|
||||
override fun event(event: Event) {
|
||||
when (event) {
|
||||
is OnThemeChanged -> {
|
||||
updateState { it.copy(theme = it.theme.next()) }
|
||||
}
|
||||
|
||||
is OnThemeVariantChanged -> {
|
||||
updateState {
|
||||
it.copy(
|
||||
themeVariant = it.themeVariant.next(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package net.thunderbird.ui.catalog.ui.common
|
||||
|
||||
import androidx.compose.material.icons.filled.DarkMode
|
||||
import androidx.compose.material.icons.filled.LightMode
|
||||
import androidx.compose.material.icons.filled.ShuffleOn
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonIcon
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.TopAppBarWithMenuButton
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.Theme
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.ThemeVariant
|
||||
import androidx.compose.material.icons.Icons as MaterialIcons
|
||||
|
||||
@Composable
|
||||
fun ThemeTopAppBar(
|
||||
onMenuClick: () -> Unit,
|
||||
theme: Theme,
|
||||
themeVariant: ThemeVariant,
|
||||
onThemeClick: () -> Unit,
|
||||
onThemeVariantClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
TopAppBarWithMenuButton(
|
||||
title = "${theme.displayName} Catalog",
|
||||
onMenuClick = onMenuClick,
|
||||
actions = {
|
||||
ButtonIcon(
|
||||
onClick = onThemeClick,
|
||||
imageVector = MaterialIcons.Filled.ShuffleOn,
|
||||
contentDescription = "${theme.displayName} Theme",
|
||||
)
|
||||
ButtonIcon(
|
||||
onClick = onThemeVariantClick,
|
||||
imageVector = when (themeVariant) {
|
||||
ThemeVariant.LIGHT -> MaterialIcons.Filled.DarkMode
|
||||
ThemeVariant.DARK -> MaterialIcons.Filled.LightMode
|
||||
},
|
||||
contentDescription = "${theme.displayName} Theme Variant",
|
||||
)
|
||||
},
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
package net.thunderbird.ui.catalog.ui.common.drawer
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.drawer.ModalDrawerSheet
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.drawer.NavigationDrawerDivider
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.drawer.NavigationDrawerHeadline
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.drawer.NavigationDrawerItem
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.Theme
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.ThemeVariant
|
||||
import net.thunderbird.ui.catalog.ui.next
|
||||
|
||||
@Suppress("LongParameterList", "LongMethod")
|
||||
@Composable
|
||||
fun DrawerContent(
|
||||
closeDrawer: () -> Unit,
|
||||
theme: Theme,
|
||||
themeVariant: ThemeVariant,
|
||||
onThemeChanged: () -> Unit,
|
||||
onThemeVariantChanged: () -> Unit,
|
||||
onNavigateToAtoms: () -> Unit,
|
||||
onNavigateToMolecules: () -> Unit,
|
||||
onNavigateToOrganisms: () -> Unit,
|
||||
onNavigateToTemplates: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
ModalDrawerSheet(
|
||||
modifier = modifier,
|
||||
) {
|
||||
NavigationDrawerHeadline(
|
||||
title = "Design system",
|
||||
)
|
||||
NavigationDrawerItem(
|
||||
label = "Atoms",
|
||||
selected = false,
|
||||
onClick = {
|
||||
closeDrawer()
|
||||
onNavigateToAtoms()
|
||||
},
|
||||
)
|
||||
NavigationDrawerItem(
|
||||
label = "Molecules",
|
||||
selected = false,
|
||||
onClick = {
|
||||
closeDrawer()
|
||||
onNavigateToMolecules()
|
||||
},
|
||||
)
|
||||
NavigationDrawerItem(
|
||||
label = "Organisms",
|
||||
selected = false,
|
||||
onClick = {
|
||||
closeDrawer()
|
||||
onNavigateToOrganisms()
|
||||
},
|
||||
)
|
||||
NavigationDrawerItem(
|
||||
label = "Templates",
|
||||
selected = false,
|
||||
onClick = {
|
||||
closeDrawer()
|
||||
onNavigateToTemplates()
|
||||
},
|
||||
)
|
||||
|
||||
NavigationDrawerDivider()
|
||||
|
||||
NavigationDrawerHeadline(
|
||||
title = "Theme",
|
||||
)
|
||||
|
||||
NavigationDrawerItem(
|
||||
label = buildAnnotatedString {
|
||||
append("Change to ")
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(theme.next().displayName)
|
||||
}
|
||||
append(" theme")
|
||||
},
|
||||
selected = false,
|
||||
onClick = {
|
||||
closeDrawer()
|
||||
onThemeChanged()
|
||||
},
|
||||
)
|
||||
|
||||
NavigationDrawerItem(
|
||||
label = buildAnnotatedString {
|
||||
append("Change to ")
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(themeVariant.next().displayName)
|
||||
}
|
||||
append(" theme variant")
|
||||
},
|
||||
selected = false,
|
||||
onClick = {
|
||||
closeDrawer()
|
||||
onThemeVariantChanged()
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package net.thunderbird.ui.catalog.ui.common.theme
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import app.k9mail.core.ui.compose.theme2.k9mail.K9MailTheme2
|
||||
import app.k9mail.core.ui.compose.theme2.thunderbird.ThunderbirdTheme2
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.Theme
|
||||
import net.thunderbird.ui.catalog.ui.CatalogContract.ThemeVariant
|
||||
|
||||
@Composable
|
||||
fun ThemeSwitch(
|
||||
theme: Theme,
|
||||
themeVariant: ThemeVariant,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
when (theme) {
|
||||
Theme.THEME_2_K9 -> K9Theme2Switch(
|
||||
themeVariant = themeVariant,
|
||||
content = content,
|
||||
)
|
||||
|
||||
Theme.THEME_2_THUNDERBIRD -> ThunderbirdTheme2Switch(
|
||||
themeVariant = themeVariant,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun K9Theme2Switch(
|
||||
themeVariant: ThemeVariant,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
when (themeVariant) {
|
||||
ThemeVariant.LIGHT -> K9MailTheme2(
|
||||
darkTheme = false,
|
||||
content = content,
|
||||
)
|
||||
|
||||
ThemeVariant.DARK -> K9MailTheme2(
|
||||
darkTheme = true,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ThunderbirdTheme2Switch(
|
||||
themeVariant: ThemeVariant,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
when (themeVariant) {
|
||||
ThemeVariant.LIGHT -> ThunderbirdTheme2(
|
||||
darkTheme = false,
|
||||
content = content,
|
||||
)
|
||||
|
||||
ThemeVariant.DARK -> ThunderbirdTheme2(
|
||||
darkTheme = true,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package net.thunderbird.ui.catalog.ui.navigation
|
||||
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
|
||||
@Composable
|
||||
fun CatalogNavHost(
|
||||
navController: NavHostController,
|
||||
modifier: Modifier = Modifier,
|
||||
paddingValues: PaddingValues = PaddingValues(),
|
||||
startDestination: CatalogRoute = CatalogRoute.Atom,
|
||||
catalogNavigation: CatalogNavigation = DefaultCatalogNavigation(),
|
||||
) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = startDestination,
|
||||
modifier = modifier.padding(paddingValues),
|
||||
) {
|
||||
catalogNavigation.registerRoutes(
|
||||
navGraphBuilder = this,
|
||||
onBack = { navController.popBackStack() },
|
||||
onFinish = { navController.popBackStack() },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package net.thunderbird.ui.catalog.ui.navigation
|
||||
|
||||
import app.k9mail.core.ui.compose.navigation.Navigation
|
||||
|
||||
interface CatalogNavigation : Navigation<CatalogRoute>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package net.thunderbird.ui.catalog.ui.navigation
|
||||
|
||||
import app.k9mail.core.ui.compose.navigation.Route
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
sealed interface CatalogRoute : Route {
|
||||
|
||||
@Serializable
|
||||
data object Atom : CatalogRoute {
|
||||
override val basePath: String = BASE_PATH
|
||||
|
||||
override fun route(): String = basePath
|
||||
|
||||
const val BASE_PATH = "$CATALOG_BASE_PATH/atom"
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data object Molecule : CatalogRoute {
|
||||
override val basePath: String = BASE_PATH
|
||||
|
||||
override fun route(): String = basePath
|
||||
|
||||
const val BASE_PATH = "$CATALOG_BASE_PATH/molecule"
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data object Organism : CatalogRoute {
|
||||
override val basePath: String = BASE_PATH
|
||||
|
||||
override fun route(): String = basePath
|
||||
|
||||
const val BASE_PATH = "$CATALOG_BASE_PATH/organism"
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data object Template : CatalogRoute {
|
||||
override val basePath: String = BASE_PATH
|
||||
|
||||
override fun route(): String = basePath
|
||||
|
||||
const val BASE_PATH = "$CATALOG_BASE_PATH/template"
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val CATALOG_BASE_PATH = "app://catalog"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package net.thunderbird.ui.catalog.ui.navigation
|
||||
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import app.k9mail.core.ui.compose.navigation.deepLinkComposable
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.CatalogAtomScreen
|
||||
import net.thunderbird.ui.catalog.ui.page.molecule.CatalogMoleculeScreen
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.CatalogOrganismScreen
|
||||
import net.thunderbird.ui.catalog.ui.page.template.CatalogTemplateScreen
|
||||
|
||||
class DefaultCatalogNavigation : CatalogNavigation {
|
||||
|
||||
override fun registerRoutes(
|
||||
navGraphBuilder: NavGraphBuilder,
|
||||
onBack: () -> Unit,
|
||||
onFinish: (CatalogRoute) -> Unit,
|
||||
) {
|
||||
with(navGraphBuilder) {
|
||||
deepLinkComposable<CatalogRoute.Atom>(
|
||||
basePath = CatalogRoute.Atom.BASE_PATH,
|
||||
) { backStackEntry ->
|
||||
CatalogAtomScreen()
|
||||
}
|
||||
|
||||
deepLinkComposable<CatalogRoute.Molecule>(
|
||||
basePath = CatalogRoute.Molecule.BASE_PATH,
|
||||
) { backStackEntry ->
|
||||
CatalogMoleculeScreen()
|
||||
}
|
||||
|
||||
deepLinkComposable<CatalogRoute.Organism>(
|
||||
basePath = CatalogRoute.Organism.BASE_PATH,
|
||||
) { backStackEntry ->
|
||||
CatalogOrganismScreen()
|
||||
}
|
||||
|
||||
deepLinkComposable<CatalogRoute.Template>(
|
||||
basePath = CatalogRoute.Template.BASE_PATH,
|
||||
) { backStackEntry ->
|
||||
CatalogTemplateScreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package net.thunderbird.ui.catalog.ui.page
|
||||
|
||||
import app.k9mail.core.ui.compose.common.mvi.UnidirectionalViewModel
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.CatalogAtomPage
|
||||
|
||||
interface CatalogPageContract {
|
||||
|
||||
interface CatalogPage {
|
||||
val displayName: String
|
||||
val isFullScreen: Boolean
|
||||
}
|
||||
|
||||
interface ViewModel : UnidirectionalViewModel<State, Event, Nothing>
|
||||
|
||||
data class State(
|
||||
val page: CatalogPage = CatalogAtomPage.TYPOGRAPHY,
|
||||
)
|
||||
|
||||
sealed interface Event {
|
||||
data class OnPageChanged(
|
||||
val page: CatalogPage,
|
||||
) : Event
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package net.thunderbird.ui.catalog.ui.page
|
||||
|
||||
import app.k9mail.core.ui.compose.common.mvi.BaseViewModel
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.Event
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.State
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.ViewModel
|
||||
|
||||
class CatalogPageViewModel(
|
||||
initialState: State = State(),
|
||||
) : BaseViewModel<State, Event, Nothing>(initialState), ViewModel {
|
||||
|
||||
override fun event(event: Event) {
|
||||
when (event) {
|
||||
is Event.OnPageChanged -> {
|
||||
updateState {
|
||||
it.copy(
|
||||
page = event.page,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.CatalogAtomPage.BUTTON
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.CatalogAtomPage.CARD
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.CatalogAtomPage.COLOR
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.CatalogAtomPage.ICON
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.CatalogAtomPage.IMAGE
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.CatalogAtomPage.SELECTION_CONTROL
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.CatalogAtomPage.TEXT_FIELD
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.CatalogAtomPage.TYPOGRAPHY
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.items.buttonItems
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.items.cardItems
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.items.colorItems
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.items.iconItems
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.items.imageItems
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.items.selectionControlItems
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.items.textFieldItems
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.items.typographyItems
|
||||
import net.thunderbird.ui.catalog.ui.page.common.PagedContent
|
||||
|
||||
@Composable
|
||||
fun CatalogAtomContent(
|
||||
pages: ImmutableList<CatalogAtomPage>,
|
||||
initialPage: CatalogAtomPage,
|
||||
onEvent: (CatalogPageContract.Event) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
PagedContent(
|
||||
pages = pages,
|
||||
initialPage = initialPage,
|
||||
modifier = modifier,
|
||||
onRenderPage = {
|
||||
when (it) {
|
||||
TYPOGRAPHY -> typographyItems()
|
||||
COLOR -> colorItems()
|
||||
BUTTON -> buttonItems()
|
||||
SELECTION_CONTROL -> selectionControlItems()
|
||||
TEXT_FIELD -> textFieldItems()
|
||||
ICON -> iconItems()
|
||||
IMAGE -> imageItems()
|
||||
CARD -> cardItems()
|
||||
}
|
||||
},
|
||||
onRenderFullScreenPage = {},
|
||||
onEvent = onEvent,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom
|
||||
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.CatalogPage
|
||||
|
||||
enum class CatalogAtomPage(
|
||||
override val displayName: String,
|
||||
override val isFullScreen: Boolean = false,
|
||||
) : CatalogPage {
|
||||
TYPOGRAPHY("Typography"),
|
||||
COLOR("Colors"),
|
||||
BUTTON("Buttons"),
|
||||
SELECTION_CONTROL("Selection Controls"),
|
||||
TEXT_FIELD("TextFields"),
|
||||
ICON("Icons"),
|
||||
IMAGE("Images"),
|
||||
CARD("Cards"),
|
||||
;
|
||||
|
||||
override fun toString(): String {
|
||||
return displayName
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun all() = entries.toImmutableList()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.common.mvi.observe
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.ViewModel
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageViewModel
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@Composable
|
||||
fun CatalogAtomScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: ViewModel = koinViewModel<CatalogPageViewModel>(),
|
||||
) {
|
||||
val (state, dispatch) = viewModel.observe { }
|
||||
|
||||
CatalogAtomContent(
|
||||
pages = CatalogAtomPage.all(),
|
||||
initialPage = state.value.page as? CatalogAtomPage ?: CatalogAtomPage.TYPOGRAPHY,
|
||||
onEvent = { dispatch(it) },
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom.items
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonElevated
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonFilled
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonFilledTonal
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonIcon
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonOutlined
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonSegmentedSingleChoice
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonText
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.RadioButton
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItemPadding
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.wideItem
|
||||
|
||||
@Suppress("LongMethod")
|
||||
fun LazyGridScope.buttonItems() {
|
||||
sectionHeaderItem(text = "Button - Filled")
|
||||
defaultItem {
|
||||
ButtonFilled(
|
||||
text = "Enabled",
|
||||
onClick = { },
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
defaultItem {
|
||||
ButtonFilled(
|
||||
text = "Disabled",
|
||||
onClick = { },
|
||||
enabled = false,
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "Button - Filled Tonal")
|
||||
defaultItem {
|
||||
ButtonFilledTonal(
|
||||
text = "Enabled",
|
||||
onClick = { },
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
defaultItem {
|
||||
ButtonFilledTonal(
|
||||
text = "Disabled",
|
||||
onClick = { },
|
||||
enabled = false,
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "Button - Elevated")
|
||||
defaultItem {
|
||||
ButtonElevated(
|
||||
text = "Enabled",
|
||||
onClick = { },
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
defaultItem {
|
||||
ButtonElevated(
|
||||
text = "Disabled",
|
||||
onClick = { },
|
||||
enabled = false,
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "Button - Outlined")
|
||||
defaultItem {
|
||||
ButtonOutlined(
|
||||
text = "Enabled",
|
||||
onClick = { },
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
defaultItem {
|
||||
ButtonOutlined(
|
||||
text = "Disabled",
|
||||
onClick = { },
|
||||
enabled = false,
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "Button - Text")
|
||||
defaultItem {
|
||||
ButtonText(
|
||||
text = "Enabled",
|
||||
onClick = { },
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
defaultItem {
|
||||
ButtonText(
|
||||
text = "Disabled",
|
||||
onClick = { },
|
||||
enabled = false,
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "Button - Icon")
|
||||
defaultItem {
|
||||
ButtonIcon(
|
||||
imageVector = Icons.Outlined.AccountCircle,
|
||||
onClick = { },
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
defaultItem {
|
||||
ButtonIcon(
|
||||
imageVector = Icons.Outlined.AccountCircle,
|
||||
onClick = { },
|
||||
enabled = false,
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "Button - RadioButton")
|
||||
defaultItem {
|
||||
RadioButton(
|
||||
selected = false,
|
||||
label = "Radio Button",
|
||||
onClick = { },
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
defaultItem {
|
||||
RadioButton(
|
||||
selected = true,
|
||||
label = "Selected Radio Button",
|
||||
onClick = { },
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "Button - Segmented Single Choice")
|
||||
wideItem {
|
||||
val options = persistentListOf(
|
||||
"Option 1",
|
||||
"Option 2",
|
||||
"Option 3",
|
||||
)
|
||||
var selectedOption by remember { mutableStateOf(options[0]) }
|
||||
|
||||
ButtonSegmentedSingleChoice(
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
onClick = {
|
||||
selectedOption = it
|
||||
},
|
||||
options = options,
|
||||
optionTitle = { it },
|
||||
selectedOption = selectedOption,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom.items
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.card.CardElevated
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.card.CardFilled
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.card.CardOutlined
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyLarge
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.wideItem
|
||||
|
||||
fun LazyGridScope.cardItems() {
|
||||
sectionCardElevated()
|
||||
sectionCardFilled()
|
||||
sectionCardOutlined()
|
||||
}
|
||||
|
||||
fun LazyGridScope.sectionCardElevated() {
|
||||
sectionHeaderItem(text = "Card - Elevated")
|
||||
wideItem {
|
||||
CardElevated(
|
||||
modifier = Modifier.padding(horizontal = MainTheme.spacings.triple),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.padding(MainTheme.spacings.triple),
|
||||
) {
|
||||
TextBodyLarge(text = "Inside a CardElevated")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun LazyGridScope.sectionCardFilled() {
|
||||
sectionHeaderItem(text = "Card - Filled")
|
||||
wideItem {
|
||||
CardFilled(
|
||||
modifier = Modifier.padding(horizontal = MainTheme.spacings.triple),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.padding(MainTheme.spacings.triple),
|
||||
) {
|
||||
TextBodyLarge(text = "Inside a CardFilled")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun LazyGridScope.sectionCardOutlined() {
|
||||
sectionHeaderItem(text = "Card - Outlined")
|
||||
wideItem {
|
||||
CardOutlined(
|
||||
modifier = Modifier.padding(horizontal = MainTheme.spacings.triple),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.padding(MainTheme.spacings.triple),
|
||||
) {
|
||||
TextBodyLarge(text = "Inside a CardOutlined")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom.items
|
||||
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import net.thunderbird.ui.catalog.ui.page.atom.view.ColorContent
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.wideItem
|
||||
|
||||
@Suppress("LongMethod")
|
||||
fun LazyGridScope.colorItems() {
|
||||
sectionHeaderItem(text = "Material 3 theme colors")
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Primary",
|
||||
color = MainTheme.colors.primary,
|
||||
textColor = MainTheme.colors.onPrimary,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Primary",
|
||||
color = MainTheme.colors.onPrimary,
|
||||
textColor = MainTheme.colors.primary,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Primary Container",
|
||||
color = MainTheme.colors.primaryContainer,
|
||||
textColor = MainTheme.colors.onPrimaryContainer,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Primary Container",
|
||||
color = MainTheme.colors.onPrimaryContainer,
|
||||
textColor = MainTheme.colors.primaryContainer,
|
||||
)
|
||||
}
|
||||
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Secondary",
|
||||
color = MainTheme.colors.secondary,
|
||||
textColor = MainTheme.colors.onSecondary,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Secondary",
|
||||
color = MainTheme.colors.onSecondary,
|
||||
textColor = MainTheme.colors.secondary,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Secondary Container",
|
||||
color = MainTheme.colors.secondaryContainer,
|
||||
textColor = MainTheme.colors.onSecondaryContainer,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Secondary Container",
|
||||
color = MainTheme.colors.onSecondaryContainer,
|
||||
textColor = MainTheme.colors.secondaryContainer,
|
||||
)
|
||||
}
|
||||
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Tertiary",
|
||||
color = MainTheme.colors.tertiary,
|
||||
textColor = MainTheme.colors.onTertiary,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Tertiary",
|
||||
color = MainTheme.colors.onTertiary,
|
||||
textColor = MainTheme.colors.tertiary,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Tertiary Container",
|
||||
color = MainTheme.colors.tertiaryContainer,
|
||||
textColor = MainTheme.colors.onTertiaryContainer,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Tertiary Container",
|
||||
color = MainTheme.colors.onTertiaryContainer,
|
||||
textColor = MainTheme.colors.tertiaryContainer,
|
||||
)
|
||||
}
|
||||
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Error",
|
||||
color = MainTheme.colors.error,
|
||||
textColor = MainTheme.colors.onError,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Error",
|
||||
color = MainTheme.colors.onError,
|
||||
textColor = MainTheme.colors.error,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Error Container",
|
||||
color = MainTheme.colors.errorContainer,
|
||||
textColor = MainTheme.colors.onErrorContainer,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Error Container",
|
||||
color = MainTheme.colors.onErrorContainer,
|
||||
textColor = MainTheme.colors.errorContainer,
|
||||
)
|
||||
}
|
||||
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Surface",
|
||||
color = MainTheme.colors.surface,
|
||||
textColor = MainTheme.colors.onSurface,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Surface",
|
||||
color = MainTheme.colors.onSurface,
|
||||
textColor = MainTheme.colors.surface,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Surface Variant",
|
||||
color = MainTheme.colors.onSurfaceVariant,
|
||||
textColor = MainTheme.colors.surface,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Surface Container Lowest",
|
||||
color = MainTheme.colors.surfaceContainerLowest,
|
||||
textColor = MainTheme.colors.onSurface,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Surface Container Low",
|
||||
color = MainTheme.colors.surfaceContainerLow,
|
||||
textColor = MainTheme.colors.onSurface,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Surface Container",
|
||||
color = MainTheme.colors.surfaceContainer,
|
||||
textColor = MainTheme.colors.onSurface,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Surface Container High",
|
||||
color = MainTheme.colors.surfaceContainerHigh,
|
||||
textColor = MainTheme.colors.onSurface,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Surface Container Highest",
|
||||
color = MainTheme.colors.surfaceContainerHighest,
|
||||
textColor = MainTheme.colors.onSurface,
|
||||
)
|
||||
}
|
||||
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Inverse Surface",
|
||||
color = MainTheme.colors.inverseSurface,
|
||||
textColor = MainTheme.colors.inverseOnSurface,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Inverse On Surface",
|
||||
color = MainTheme.colors.inverseOnSurface,
|
||||
textColor = MainTheme.colors.inverseSurface,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Inverse Primary",
|
||||
color = MainTheme.colors.inversePrimary,
|
||||
textColor = MainTheme.colors.onPrimaryContainer,
|
||||
)
|
||||
}
|
||||
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Outline",
|
||||
color = MainTheme.colors.outline,
|
||||
textColor = MainTheme.colors.surface,
|
||||
)
|
||||
}
|
||||
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Outline Variant",
|
||||
color = MainTheme.colors.outlineVariant,
|
||||
textColor = MainTheme.colors.inverseSurface,
|
||||
)
|
||||
}
|
||||
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Surface Bright",
|
||||
color = MainTheme.colors.surfaceBright,
|
||||
textColor = MainTheme.colors.onSurface,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Surface Dim",
|
||||
color = MainTheme.colors.surfaceDim,
|
||||
textColor = MainTheme.colors.onSurface,
|
||||
)
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "Material 3 theme custom colors")
|
||||
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Info",
|
||||
color = MainTheme.colors.info,
|
||||
textColor = MainTheme.colors.onInfo,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Info",
|
||||
color = MainTheme.colors.onInfo,
|
||||
textColor = MainTheme.colors.info,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Info Container",
|
||||
color = MainTheme.colors.infoContainer,
|
||||
textColor = MainTheme.colors.onInfoContainer,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Info Container",
|
||||
color = MainTheme.colors.onInfoContainer,
|
||||
textColor = MainTheme.colors.infoContainer,
|
||||
)
|
||||
}
|
||||
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Success",
|
||||
color = MainTheme.colors.success,
|
||||
textColor = MainTheme.colors.onSuccess,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Success",
|
||||
color = MainTheme.colors.onSuccess,
|
||||
textColor = MainTheme.colors.success,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Success Container",
|
||||
color = MainTheme.colors.successContainer,
|
||||
textColor = MainTheme.colors.onSuccessContainer,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Success Container",
|
||||
color = MainTheme.colors.onSuccessContainer,
|
||||
textColor = MainTheme.colors.successContainer,
|
||||
)
|
||||
}
|
||||
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Warning",
|
||||
color = MainTheme.colors.warning,
|
||||
textColor = MainTheme.colors.onWarning,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Warning",
|
||||
color = MainTheme.colors.onWarning,
|
||||
textColor = MainTheme.colors.warning,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "Warning Container",
|
||||
color = MainTheme.colors.warningContainer,
|
||||
textColor = MainTheme.colors.onWarningContainer,
|
||||
)
|
||||
}
|
||||
wideItem {
|
||||
ColorContent(
|
||||
text = "On Warning Container",
|
||||
color = MainTheme.colors.onWarningContainer,
|
||||
textColor = MainTheme.colors.warningContainer,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom.items
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icon
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodySmall
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItemPadding
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionSubtitleItem
|
||||
import androidx.compose.material3.Icon as Material3Icon
|
||||
import app.k9mail.core.ui.legacy.designsystem.atom.icon.Icons as LegacyIcons
|
||||
|
||||
fun LazyGridScope.iconItems() {
|
||||
sectionHeaderItem(
|
||||
text = "Compose Icons",
|
||||
)
|
||||
sectionSubtitleItem(text = "Sizes")
|
||||
defaultItem {
|
||||
IconItem(
|
||||
name = "Small",
|
||||
imageVector = Icons.Outlined.Info,
|
||||
modifier = Modifier.size(MainTheme.sizes.iconSmall),
|
||||
)
|
||||
}
|
||||
defaultItem {
|
||||
IconItem(
|
||||
name = "Default",
|
||||
imageVector = Icons.Outlined.Info,
|
||||
modifier = Modifier.size(MainTheme.sizes.icon),
|
||||
)
|
||||
}
|
||||
defaultItem {
|
||||
IconItem(
|
||||
name = "Large",
|
||||
imageVector = Icons.Outlined.Info,
|
||||
modifier = Modifier.size(MainTheme.sizes.iconLarge),
|
||||
)
|
||||
}
|
||||
sectionSubtitleItem(text = "Filled")
|
||||
getIconsFor(Icons.Filled)
|
||||
sectionSubtitleItem(text = "Outlined")
|
||||
getIconsFor(Icons.Outlined)
|
||||
sectionHeaderItem(
|
||||
text = "Legacy Icons",
|
||||
)
|
||||
sectionSubtitleItem(text = "Filled")
|
||||
getLegacyIconsFor(LegacyIcons.Filled)
|
||||
sectionSubtitleItem(text = "Outlined")
|
||||
getLegacyIconsFor(LegacyIcons.Outlined)
|
||||
}
|
||||
|
||||
private inline fun <reified T> LazyGridScope.getIconsFor(icons: T) {
|
||||
for (method in T::class.java.methods) {
|
||||
if (exclusions.contains(method.name)) {
|
||||
continue
|
||||
} else if (method.name.startsWith("get")) {
|
||||
defaultItem {
|
||||
method.isAccessible = true
|
||||
val imageVector = method.invoke(icons) as ImageVector
|
||||
IconItem(
|
||||
name = method.name.replaceFirst("get", ""),
|
||||
imageVector = imageVector,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <reified T> LazyGridScope.getLegacyIconsFor(icons: T) {
|
||||
for (method in T::class.java.methods) {
|
||||
if (exclusions.contains(method.name)) {
|
||||
continue
|
||||
} else if (method.name.startsWith("get")) {
|
||||
defaultItem {
|
||||
method.isAccessible = true
|
||||
val drawableResId = method.invoke(icons) as Int
|
||||
LegacyIconItem(
|
||||
name = method.name.replaceFirst("get", ""),
|
||||
drawableResId = drawableResId,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val exclusions = listOf("getClass")
|
||||
|
||||
@Composable
|
||||
private fun IconItem(
|
||||
name: String,
|
||||
imageVector: ImageVector,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(defaultItemPadding()),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = imageVector,
|
||||
modifier = modifier,
|
||||
)
|
||||
TextBodySmall(text = name)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LegacyIconItem(
|
||||
name: String,
|
||||
drawableResId: Int,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(defaultItemPadding())
|
||||
.then(modifier),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
|
||||
) {
|
||||
Material3Icon(
|
||||
painter = painterResource(id = drawableResId),
|
||||
contentDescription = null,
|
||||
)
|
||||
TextBodySmall(text = name)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom.items
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
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.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icon
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.image.FixedScaleImage
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.image.RemoteImage
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodySmall
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import net.thunderbird.core.ui.compose.designsystem.atom.icon.filled.Star
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItemPadding
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.fullSpanItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionSubtitleItem
|
||||
|
||||
fun LazyGridScope.imageItems() {
|
||||
sectionHeaderItem(text = "Images")
|
||||
defaultItem {
|
||||
Image(
|
||||
painter = painterResource(id = MainTheme.images.logo),
|
||||
contentDescription = "logo",
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "Images with fixed scale")
|
||||
fixedScaleImagesCropped()
|
||||
fixedScaleImagesOverflow()
|
||||
fixedScaleImagesAlignment()
|
||||
|
||||
sectionHeaderItem(text = "Remote images")
|
||||
remoteImage(
|
||||
url = "https://www.thunderbird.net/media/img/thunderbird/favicon-196.png",
|
||||
description = "Weblink",
|
||||
)
|
||||
}
|
||||
|
||||
private fun LazyGridScope.fixedScaleImagesCropped() {
|
||||
sectionSubtitleItem(text = "Images are cropped by parent container size")
|
||||
fullSpanItem {
|
||||
FixedScaleImageView(
|
||||
description = "Small container",
|
||||
width = 40.dp,
|
||||
height = 40.dp,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
FixedScaleImageView(
|
||||
description = "Small horizontal container",
|
||||
width = 40.dp,
|
||||
height = 200.dp,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
FixedScaleImageView(
|
||||
description = "Small vertical container",
|
||||
width = 200.dp,
|
||||
height = 40.dp,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.fixedScaleImagesOverflow() {
|
||||
sectionSubtitleItem(text = "Images overflow parent container size")
|
||||
fullSpanItem {
|
||||
FixedScaleImageView(
|
||||
description = "Small container",
|
||||
width = 40.dp,
|
||||
height = 40.dp,
|
||||
allowOverflow = true,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
FixedScaleImageView(
|
||||
description = "Small horizontal container",
|
||||
width = 40.dp,
|
||||
height = 200.dp,
|
||||
allowOverflow = true,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
FixedScaleImageView(
|
||||
description = "Small vertical container",
|
||||
width = 200.dp,
|
||||
height = 40.dp,
|
||||
allowOverflow = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.fixedScaleImagesAlignment() {
|
||||
sectionSubtitleItem(text = "Images with different alignments")
|
||||
fullSpanItem {
|
||||
FixedScaleImageView(
|
||||
description = "Center",
|
||||
width = 200.dp,
|
||||
height = 200.dp,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
FixedScaleImageView(
|
||||
description = "Top center",
|
||||
width = 200.dp,
|
||||
height = 200.dp,
|
||||
alignment = Alignment.TopCenter,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
FixedScaleImageView(
|
||||
description = "Bottom center",
|
||||
width = 200.dp,
|
||||
height = 200.dp,
|
||||
alignment = Alignment.BottomCenter,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun FixedScaleImageView(
|
||||
description: String,
|
||||
width: Dp,
|
||||
height: Dp,
|
||||
alignment: Alignment = Alignment.Center,
|
||||
allowOverflow: Boolean = false,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(width)
|
||||
.height(height)
|
||||
.border(1.dp, MainTheme.colors.primary, MainTheme.shapes.small),
|
||||
) {
|
||||
FixedScaleImage(
|
||||
id = MainTheme.images.logo,
|
||||
alignment = alignment,
|
||||
allowOverflow = allowOverflow,
|
||||
)
|
||||
}
|
||||
TextBodySmall(text = description)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.remoteImage(
|
||||
url: String,
|
||||
description: String,
|
||||
) {
|
||||
fullSpanItem {
|
||||
Column(
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
RemoteImage(
|
||||
url = url,
|
||||
modifier = Modifier.size(MainTheme.sizes.large),
|
||||
placeholder = {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Star,
|
||||
)
|
||||
},
|
||||
)
|
||||
TextBodySmall(text = description)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom.items
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.Checkbox
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.RadioGroup
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.Switch
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodySmall
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItemPadding
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
|
||||
@Suppress("LongMethod")
|
||||
fun LazyGridScope.selectionControlItems() {
|
||||
sectionHeaderItem(text = "Checkbox")
|
||||
captionItem(caption = "Checked") {
|
||||
Checkbox(checked = true, onCheckedChange = {})
|
||||
}
|
||||
captionItem(caption = "Unchecked") {
|
||||
Checkbox(checked = false, onCheckedChange = {})
|
||||
}
|
||||
captionItem(caption = "Disabled Checked") {
|
||||
Checkbox(checked = true, onCheckedChange = {}, enabled = false)
|
||||
}
|
||||
captionItem(caption = "Disabled") {
|
||||
Checkbox(checked = false, onCheckedChange = {}, enabled = false)
|
||||
}
|
||||
sectionHeaderItem(text = "Switch")
|
||||
captionItem(caption = "Checked") {
|
||||
Switch(checked = true, onCheckedChange = {})
|
||||
}
|
||||
captionItem(caption = "Unchecked") {
|
||||
Switch(checked = false, onCheckedChange = {})
|
||||
}
|
||||
captionItem(caption = "Disabled Checked") {
|
||||
Switch(checked = true, onCheckedChange = {}, enabled = false)
|
||||
}
|
||||
captionItem(caption = "Disabled") {
|
||||
Switch(checked = false, onCheckedChange = {}, enabled = false)
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "Radio Group")
|
||||
defaultItem {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.padding(defaultItemPadding()),
|
||||
) {
|
||||
TextTitleMedium(text = "Selected")
|
||||
RadioGroup(
|
||||
onClick = {},
|
||||
options = radioGroupChoice,
|
||||
optionTitle = { it.second },
|
||||
selectedOption = radioGroupChoice[0],
|
||||
modifier = Modifier
|
||||
.padding(MainTheme.spacings.default)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
defaultItem {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.padding(defaultItemPadding()),
|
||||
) {
|
||||
TextTitleMedium(text = "Unselected")
|
||||
RadioGroup(
|
||||
onClick = {},
|
||||
options = radioGroupChoice,
|
||||
optionTitle = { it.second },
|
||||
modifier = Modifier
|
||||
.padding(MainTheme.spacings.default)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.captionItem(
|
||||
caption: String,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
defaultItem {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
) {
|
||||
content()
|
||||
TextBodySmall(text = caption)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val radioGroupChoice = persistentListOf(
|
||||
Pair("1", "Alpha"),
|
||||
Pair("2", "Beta"),
|
||||
Pair("3", "Gamma"),
|
||||
Pair("4", "Delta"),
|
||||
)
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom.items
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icon
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlined
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlinedEmailAddress
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlinedNumber
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlinedPassword
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlinedSelect
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.input.CheckboxInput
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import net.thunderbird.ui.catalog.ui.page.common.helper.WithRememberedState
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItemPadding
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.fullSpanItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionSubtitleItem
|
||||
|
||||
fun LazyGridScope.textFieldItems() {
|
||||
sectionHeaderItem(text = "Text field - Outlined")
|
||||
sectionSubtitleItem(text = "Default")
|
||||
textFieldOutlinedItems()
|
||||
sectionSubtitleItem(text = "Password")
|
||||
passwordTextFieldOutlinedItems()
|
||||
sectionSubtitleItem(text = "Email address")
|
||||
emailTextFieldOutlinedItems()
|
||||
sectionSubtitleItem(text = "Number")
|
||||
numberTextFieldOutlinedItems()
|
||||
sectionSubtitleItem(text = "Selection")
|
||||
selectionTextFieldOutlinedItems()
|
||||
}
|
||||
|
||||
@Stable
|
||||
data class TextFieldState<T>(
|
||||
val input: T,
|
||||
val label: String = "Label",
|
||||
val showLabel: Boolean = false,
|
||||
val showTrailingIcon: Boolean = false,
|
||||
val isDisabled: Boolean = false,
|
||||
val isReadOnly: Boolean = false,
|
||||
val isRequired: Boolean = false,
|
||||
val hasError: Boolean = false,
|
||||
val isSingleLine: Boolean = false,
|
||||
)
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
fun <T> TextFieldDemo(
|
||||
initialState: TextFieldState<T>,
|
||||
modifier: Modifier = Modifier,
|
||||
hasTrailingIcon: Boolean = false,
|
||||
hasSingleLine: Boolean = false,
|
||||
content: @Composable (state: MutableState<TextFieldState<T>>) -> Unit,
|
||||
) {
|
||||
WithRememberedState(input = initialState) { state ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(defaultItemPadding())
|
||||
.then(modifier),
|
||||
) {
|
||||
key(state.value.showLabel, state.value.isRequired) {
|
||||
content(state)
|
||||
}
|
||||
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
top = MainTheme.spacings.double,
|
||||
start = MainTheme.spacings.default,
|
||||
),
|
||||
) {
|
||||
TextTitleMedium(text = "Configuration:")
|
||||
}
|
||||
|
||||
CheckboxInput(
|
||||
text = "Show Label",
|
||||
checked = state.value.showLabel,
|
||||
onCheckedChange = { state.value = state.value.copy(showLabel = it) },
|
||||
contentPadding = defaultPadding,
|
||||
)
|
||||
|
||||
if (hasTrailingIcon) {
|
||||
CheckboxInput(
|
||||
text = "Show Trailing Icon",
|
||||
checked = state.value.showTrailingIcon,
|
||||
onCheckedChange = { state.value = state.value.copy(showTrailingIcon = it) },
|
||||
contentPadding = defaultPadding,
|
||||
)
|
||||
}
|
||||
|
||||
CheckboxInput(
|
||||
text = "Is required",
|
||||
checked = state.value.isRequired,
|
||||
onCheckedChange = { state.value = state.value.copy(isRequired = it) },
|
||||
contentPadding = defaultPadding,
|
||||
)
|
||||
|
||||
CheckboxInput(
|
||||
text = "Is read-only",
|
||||
checked = state.value.isReadOnly,
|
||||
onCheckedChange = { state.value = state.value.copy(isReadOnly = it) },
|
||||
contentPadding = defaultPadding,
|
||||
)
|
||||
|
||||
CheckboxInput(
|
||||
text = "Is disabled",
|
||||
checked = state.value.isDisabled,
|
||||
onCheckedChange = { state.value = state.value.copy(isDisabled = it) },
|
||||
contentPadding = defaultPadding,
|
||||
)
|
||||
|
||||
CheckboxInput(
|
||||
text = "Has Error",
|
||||
checked = state.value.hasError,
|
||||
onCheckedChange = { state.value = state.value.copy(hasError = it) },
|
||||
contentPadding = defaultPadding,
|
||||
)
|
||||
|
||||
if (hasSingleLine) {
|
||||
CheckboxInput(
|
||||
text = "Single line",
|
||||
checked = state.value.isSingleLine,
|
||||
onCheckedChange = { state.value = state.value.copy(isSingleLine = it) },
|
||||
contentPadding = defaultPadding,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val defaultPadding = PaddingValues(0.dp)
|
||||
|
||||
private fun LazyGridScope.textFieldOutlinedItems() {
|
||||
fullSpanItem {
|
||||
TextFieldDemo(
|
||||
hasTrailingIcon = true,
|
||||
hasSingleLine = true,
|
||||
initialState = TextFieldState(input = ""),
|
||||
) { state ->
|
||||
TextFieldOutlined(
|
||||
value = state.value.input,
|
||||
label = if (state.value.showLabel) state.value.label else null,
|
||||
onValueChange = { state.value = state.value.copy(input = it) },
|
||||
trailingIcon = {
|
||||
if (state.value.showTrailingIcon) {
|
||||
Icon(imageVector = Icons.Outlined.AccountCircle)
|
||||
}
|
||||
},
|
||||
isEnabled = !state.value.isDisabled,
|
||||
isReadOnly = state.value.isReadOnly,
|
||||
isRequired = state.value.isRequired,
|
||||
isSingleLine = state.value.isSingleLine,
|
||||
hasError = state.value.hasError,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.passwordTextFieldOutlinedItems() {
|
||||
fullSpanItem {
|
||||
TextFieldDemo(
|
||||
initialState = TextFieldState(
|
||||
input = "",
|
||||
label = "Password",
|
||||
),
|
||||
) { state ->
|
||||
TextFieldOutlinedPassword(
|
||||
value = state.value.input,
|
||||
label = if (state.value.showLabel) state.value.label else null,
|
||||
onValueChange = { state.value = state.value.copy(input = it) },
|
||||
isEnabled = !state.value.isDisabled,
|
||||
isReadOnly = state.value.isReadOnly,
|
||||
isRequired = state.value.isRequired,
|
||||
hasError = state.value.hasError,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.emailTextFieldOutlinedItems() {
|
||||
fullSpanItem {
|
||||
TextFieldDemo(
|
||||
initialState = TextFieldState(
|
||||
input = "",
|
||||
label = "Email Address",
|
||||
),
|
||||
) { state ->
|
||||
TextFieldOutlinedEmailAddress(
|
||||
value = state.value.input,
|
||||
label = if (state.value.showLabel) state.value.label else null,
|
||||
onValueChange = { state.value = state.value.copy(input = it) },
|
||||
isEnabled = !state.value.isDisabled,
|
||||
isReadOnly = state.value.isReadOnly,
|
||||
isRequired = state.value.isRequired,
|
||||
hasError = state.value.hasError,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.numberTextFieldOutlinedItems() {
|
||||
fullSpanItem {
|
||||
TextFieldDemo(
|
||||
initialState = TextFieldState<Long?>(
|
||||
input = 123L,
|
||||
label = "Number",
|
||||
),
|
||||
) { state ->
|
||||
TextFieldOutlinedNumber(
|
||||
value = state.value.input,
|
||||
label = if (state.value.showLabel) state.value.label else null,
|
||||
onValueChange = { state.value = state.value.copy(input = it) },
|
||||
isEnabled = !state.value.isDisabled,
|
||||
isReadOnly = state.value.isReadOnly,
|
||||
isRequired = state.value.isRequired,
|
||||
hasError = state.value.hasError,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private data class TextFieldSelectState(
|
||||
val options: ImmutableList<String> = persistentListOf("Option 1", "Option 2", "Option 3"),
|
||||
val selectedOption: String = options.first(),
|
||||
)
|
||||
|
||||
private fun LazyGridScope.selectionTextFieldOutlinedItems() {
|
||||
fullSpanItem {
|
||||
TextFieldDemo(
|
||||
initialState = TextFieldState(
|
||||
input = TextFieldSelectState(),
|
||||
label = "Select",
|
||||
),
|
||||
) { state ->
|
||||
key(
|
||||
state.value.input.selectedOption,
|
||||
) {
|
||||
TextFieldOutlinedSelect(
|
||||
options = state.value.input.options,
|
||||
label = if (state.value.showLabel) state.value.label else null,
|
||||
onValueChange = {
|
||||
state.value = state.value.copy(input = state.value.input.copy(selectedOption = it))
|
||||
},
|
||||
selectedOption = state.value.input.selectedOption,
|
||||
isEnabled = !state.value.isDisabled,
|
||||
isReadOnly = state.value.isReadOnly,
|
||||
isRequired = state.value.isRequired,
|
||||
hasError = state.value.hasError,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom.items
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyLarge
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodySmall
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextDisplayLarge
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextDisplayMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextDisplaySmall
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadlineLarge
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadlineMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadlineSmall
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextLabelLarge
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextLabelMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextLabelSmall
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleLarge
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleSmall
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItemPadding
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.fullSpanItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
|
||||
fun LazyGridScope.typographyItems() {
|
||||
sectionHeaderItem(text = "Text styles")
|
||||
textItems()
|
||||
|
||||
sectionHeaderItem(text = "Text styles - Colored")
|
||||
textItems(color = Color.Magenta)
|
||||
|
||||
sectionHeaderItem(text = "Text styles - Annotated")
|
||||
textItems(isAnnotated = true)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
private fun LazyGridScope.textItems(
|
||||
isAnnotated: Boolean = false,
|
||||
color: Color = Color.Unspecified,
|
||||
) {
|
||||
fullSpanItem {
|
||||
TextDisplayLarge(
|
||||
text = annotatedString("DisplayLarge", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
TextDisplayMedium(
|
||||
text = annotatedString("DisplayMedium", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
TextDisplaySmall(
|
||||
text = annotatedString("DisplaySmall", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
|
||||
fullSpanItem {
|
||||
TextHeadlineLarge(
|
||||
text = annotatedString("HeadlineLarge", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
TextHeadlineMedium(
|
||||
text = annotatedString("HeadlineMedium", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
TextHeadlineSmall(
|
||||
text = annotatedString("HeadlineSmall", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
|
||||
fullSpanItem {
|
||||
TextTitleLarge(
|
||||
text = annotatedString("TitleLarge", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
TextTitleMedium(
|
||||
text = annotatedString("TitleMedium", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
TextTitleSmall(
|
||||
text = annotatedString("TitleSmall", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
|
||||
fullSpanItem {
|
||||
TextBodyLarge(
|
||||
text = annotatedString("BodyLarge", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
TextBodyMedium(
|
||||
text = annotatedString("BodyMedium", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
TextBodySmall(
|
||||
text = annotatedString("BodySmall", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
|
||||
fullSpanItem {
|
||||
TextLabelLarge(
|
||||
text = annotatedString("LabelLarge", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
TextLabelMedium(
|
||||
text = annotatedString("LabelMedium", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
fullSpanItem {
|
||||
TextLabelSmall(
|
||||
text = annotatedString("LabelSmall", isAnnotated),
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun annotatedString(
|
||||
name: String,
|
||||
isAnnotated: Boolean,
|
||||
) = buildAnnotatedString {
|
||||
append(name)
|
||||
if (isAnnotated) {
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append("Annotated")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.atom.view
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.Surface
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyLarge
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodySmall
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItemPadding
|
||||
|
||||
@Composable
|
||||
internal fun ColorContent(
|
||||
text: String,
|
||||
color: Color,
|
||||
textColor: Color,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Surface(
|
||||
color = color,
|
||||
modifier = Modifier
|
||||
.padding(defaultItemPadding())
|
||||
.then(modifier),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(MainTheme.spacings.double),
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
|
||||
) {
|
||||
TextBodyLarge(
|
||||
text = text,
|
||||
color = textColor,
|
||||
)
|
||||
TextBodySmall(
|
||||
text = color.toHex(),
|
||||
color = textColor,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Color.toHex(): String {
|
||||
return "#${Integer.toHexString(toArgb()).uppercase()}"
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.common
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material3.ScrollableTabRow
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.template.ResponsiveContentWithSurface
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.launch
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.CatalogPage
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.fullSpanItem
|
||||
|
||||
@Composable
|
||||
fun <T : CatalogPage> PagedContent(
|
||||
pages: ImmutableList<T>,
|
||||
initialPage: T,
|
||||
onRenderPage: LazyGridScope.(T) -> Unit,
|
||||
onEvent: (CatalogPageContract.Event) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onRenderFullScreenPage: @Composable (T) -> Unit = {},
|
||||
) {
|
||||
val pagerState = rememberPagerState(
|
||||
initialPage = pages.indexOf(initialPage),
|
||||
initialPageOffsetFraction = 0f,
|
||||
) {
|
||||
pages.size
|
||||
}
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
LaunchedEffect(pagerState.settledPage) {
|
||||
onEvent(CatalogPageContract.Event.OnPageChanged(pages[pagerState.settledPage]))
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = modifier,
|
||||
) {
|
||||
ScrollableTabRow(
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
) {
|
||||
pages.forEachIndexed { index, title ->
|
||||
Tab(
|
||||
selected = pagerState.currentPage == index,
|
||||
onClick = {
|
||||
coroutineScope.launch {
|
||||
pagerState.animateScrollToPage(index)
|
||||
onEvent(CatalogPageContract.Event.OnPageChanged(pages[index]))
|
||||
}
|
||||
},
|
||||
text = { Text(text = title.toString()) },
|
||||
)
|
||||
}
|
||||
}
|
||||
ResponsiveContentWithSurface {
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
modifier = Modifier
|
||||
.fillMaxSize(),
|
||||
) { pageIndex ->
|
||||
if (pages[pageIndex].isFullScreen) {
|
||||
onRenderFullScreenPage(pages[pageIndex])
|
||||
} else {
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Adaptive(MainTheme.sizes.larger),
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.imePadding(),
|
||||
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
|
||||
) {
|
||||
onRenderPage(pages[pageIndex])
|
||||
fullSpanItem { Spacer(modifier = Modifier.height(MainTheme.sizes.smaller)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.common.helper
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
|
||||
@Composable
|
||||
internal fun <T> WithRememberedState(
|
||||
input: T,
|
||||
content: @Composable (state: MutableState<T>) -> Unit,
|
||||
) {
|
||||
val state = remember { mutableStateOf(input) }
|
||||
content(state)
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.common.list
|
||||
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridItemScope
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import java.util.UUID
|
||||
|
||||
fun LazyGridScope.defaultItem(content: @Composable LazyGridItemScope.() -> Unit) {
|
||||
item(
|
||||
key = UUID.randomUUID().toString(),
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.common.list
|
||||
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.runtime.Composable
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
|
||||
@Composable
|
||||
fun defaultItemPadding(): PaddingValues = PaddingValues(
|
||||
horizontal = MainTheme.spacings.double,
|
||||
)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.common.list
|
||||
|
||||
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridItemScope
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import java.util.UUID
|
||||
|
||||
fun LazyGridScope.fullSpanItem(content: @Composable LazyGridItemScope.() -> Unit) {
|
||||
item(
|
||||
key = UUID.randomUUID().toString(),
|
||||
span = { GridItemSpan(maxLineSpan) },
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.common.list
|
||||
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
|
||||
@Composable
|
||||
fun ItemOutlinedView(
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
|
||||
modifier = Modifier
|
||||
.padding(defaultItemPadding())
|
||||
.then(modifier),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.border(1.dp, Color.Gray)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.common.list
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.DividerHorizontal
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleLarge
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
|
||||
fun LazyGridScope.sectionHeaderItem(
|
||||
text: String,
|
||||
) {
|
||||
fullSpanItem {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = MainTheme.spacings.double,
|
||||
top = MainTheme.spacings.double,
|
||||
end = MainTheme.spacings.double,
|
||||
),
|
||||
) {
|
||||
TextTitleLarge(
|
||||
text = text,
|
||||
)
|
||||
DividerHorizontal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.common.list
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodySmall
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
|
||||
fun LazyGridScope.sectionInfoItem(
|
||||
text: String,
|
||||
) {
|
||||
fullSpanItem {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = MainTheme.spacings.double,
|
||||
end = MainTheme.spacings.double,
|
||||
),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
TextBodySmall(
|
||||
text = text,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.common.list
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.DividerHorizontal
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
|
||||
fun LazyGridScope.sectionSubtitleItem(
|
||||
text: String,
|
||||
) {
|
||||
fullSpanItem {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = MainTheme.spacings.double,
|
||||
top = MainTheme.spacings.default,
|
||||
end = MainTheme.spacings.double,
|
||||
),
|
||||
) {
|
||||
TextTitleMedium(
|
||||
text = text,
|
||||
)
|
||||
DividerHorizontal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.common.list
|
||||
|
||||
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridItemScope
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import java.util.UUID
|
||||
|
||||
fun LazyGridScope.wideItem(content: @Composable LazyGridItemScope.() -> Unit) {
|
||||
item(
|
||||
key = UUID.randomUUID().toString(),
|
||||
span = { GridItemSpan(2) },
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.molecule
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract
|
||||
import net.thunderbird.ui.catalog.ui.page.common.PagedContent
|
||||
import net.thunderbird.ui.catalog.ui.page.molecule.CatalogMoleculePage.INPUT
|
||||
import net.thunderbird.ui.catalog.ui.page.molecule.CatalogMoleculePage.PULL_TO_REFRESH
|
||||
import net.thunderbird.ui.catalog.ui.page.molecule.CatalogMoleculePage.STATE
|
||||
import net.thunderbird.ui.catalog.ui.page.molecule.items.PullToRefresh
|
||||
import net.thunderbird.ui.catalog.ui.page.molecule.items.inputItems
|
||||
import net.thunderbird.ui.catalog.ui.page.molecule.items.stateItems
|
||||
|
||||
@Composable
|
||||
fun CatalogMoleculeContent(
|
||||
pages: ImmutableList<CatalogMoleculePage>,
|
||||
initialPage: CatalogMoleculePage,
|
||||
onEvent: (CatalogPageContract.Event) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
PagedContent(
|
||||
pages = pages,
|
||||
initialPage = initialPage,
|
||||
modifier = modifier,
|
||||
onRenderPage = {
|
||||
when (it) {
|
||||
INPUT -> inputItems()
|
||||
STATE -> stateItems()
|
||||
else -> throw IllegalArgumentException("Unknown page: $it")
|
||||
}
|
||||
},
|
||||
onRenderFullScreenPage = { page ->
|
||||
when (page) {
|
||||
PULL_TO_REFRESH -> PullToRefresh()
|
||||
else -> throw IllegalArgumentException("Unknown page: $page")
|
||||
}
|
||||
},
|
||||
onEvent = onEvent,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.molecule
|
||||
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.CatalogPage
|
||||
|
||||
enum class CatalogMoleculePage(
|
||||
override val displayName: String,
|
||||
override val isFullScreen: Boolean = false,
|
||||
) : CatalogPage {
|
||||
INPUT("Inputs"),
|
||||
STATE("States"),
|
||||
PULL_TO_REFRESH("Pull to refresh", isFullScreen = true),
|
||||
;
|
||||
|
||||
override fun toString(): String {
|
||||
return displayName
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun all() = entries.toImmutableList()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.molecule
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.common.mvi.observe
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.ViewModel
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageViewModel
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@Composable
|
||||
fun CatalogMoleculeScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: ViewModel = koinViewModel<CatalogPageViewModel>(),
|
||||
) {
|
||||
val (state, dispatch) = viewModel.observe { }
|
||||
|
||||
CatalogMoleculeContent(
|
||||
pages = CatalogMoleculePage.all(),
|
||||
initialPage = state.value.page as? CatalogMoleculePage ?: CatalogMoleculePage.INPUT,
|
||||
onEvent = { dispatch(it) },
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.molecule.items
|
||||
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.input.CheckboxInput
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.input.EmailAddressInput
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.input.NumberInput
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.input.PasswordInput
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.input.SelectInput
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.input.SwitchInput
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.input.TextInput
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import net.thunderbird.ui.catalog.ui.page.common.helper.WithRememberedState
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.ItemOutlinedView
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.fullSpanItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionSubtitleItem
|
||||
|
||||
@Suppress("LongMethod")
|
||||
fun LazyGridScope.inputItems() {
|
||||
sectionHeaderItem(text = "TextInput")
|
||||
sectionSubtitleItem(text = "Default")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState(input = "") { state ->
|
||||
TextInput(
|
||||
text = state.value,
|
||||
onTextChange = { state.value = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With error")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState(input = "") { state ->
|
||||
TextInput(
|
||||
text = state.value,
|
||||
onTextChange = { state.value = it },
|
||||
errorMessage = "Invalid input",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "EmailAddressInput")
|
||||
sectionSubtitleItem(text = "Default")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState(input = "") { state ->
|
||||
EmailAddressInput(
|
||||
emailAddress = state.value,
|
||||
onEmailAddressChange = { state.value = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With error")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState(input = "wrong email address") { state ->
|
||||
EmailAddressInput(
|
||||
emailAddress = state.value,
|
||||
onEmailAddressChange = { state.value = it },
|
||||
errorMessage = "Invalid email address",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "NumberInput")
|
||||
sectionSubtitleItem(text = "Default")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState<Long?>(input = null) { state ->
|
||||
NumberInput(
|
||||
value = state.value,
|
||||
onValueChange = { state.value = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With error")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState<Long?>(input = 123L) { state ->
|
||||
NumberInput(
|
||||
value = state.value,
|
||||
onValueChange = { state.value = it },
|
||||
errorMessage = "Invalid number",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "PasswordInput")
|
||||
sectionSubtitleItem(text = "Default")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState(input = "") { state ->
|
||||
PasswordInput(
|
||||
password = state.value,
|
||||
onPasswordChange = { state.value = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With error")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState(input = "wrong password") { state ->
|
||||
PasswordInput(
|
||||
password = state.value,
|
||||
onPasswordChange = { state.value = it },
|
||||
errorMessage = "Invalid password",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "SelectInput")
|
||||
fullSpanItem {
|
||||
val options = persistentListOf("Option 1", "Option 2", "Option 3")
|
||||
ItemOutlinedView {
|
||||
WithRememberedState(input = options.first()) { state ->
|
||||
SelectInput(
|
||||
options = options,
|
||||
selectedOption = state.value,
|
||||
onOptionChange = { state.value = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "CheckboxInput")
|
||||
sectionSubtitleItem(text = "Default")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState(input = false) { state ->
|
||||
CheckboxInput(
|
||||
text = "Check the box",
|
||||
checked = state.value,
|
||||
onCheckedChange = { state.value = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With error")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState(input = false) { state ->
|
||||
CheckboxInput(
|
||||
text = "Check the box",
|
||||
checked = state.value,
|
||||
onCheckedChange = { state.value = it },
|
||||
errorMessage = "Checkbox must be checked",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "SwitchInput")
|
||||
sectionSubtitleItem(text = "Default")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState(input = false) { state ->
|
||||
SwitchInput(
|
||||
text = "Switch the toggle",
|
||||
checked = state.value,
|
||||
onCheckedChange = { state.value = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With error")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
WithRememberedState(input = false) { state ->
|
||||
SwitchInput(
|
||||
text = "Switch the toggle",
|
||||
checked = state.value,
|
||||
onCheckedChange = { state.value = it },
|
||||
errorMessage = "Switch must be checked",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.molecule.items
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.PullToRefreshBox
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
@Composable
|
||||
fun PullToRefresh(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val isRefreshing = remember { mutableStateOf(false) }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
PullToRefreshBox(
|
||||
isRefreshing = isRefreshing.value,
|
||||
onRefresh = {
|
||||
isRefreshing.value = true
|
||||
|
||||
coroutineScope.launch {
|
||||
delay(2000)
|
||||
isRefreshing.value = false
|
||||
}
|
||||
},
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
) {
|
||||
LazyColumn(
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
|
||||
) {
|
||||
items(10) {
|
||||
TextTitleMedium(text = "Item $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.molecule.items
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.ContentLoadingErrorState
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.ContentLoadingErrorView
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.ContentLoadingState
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.ContentLoadingView
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.ErrorView
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.LoadingView
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.ItemOutlinedView
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.fullSpanItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionInfoItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionSubtitleItem
|
||||
|
||||
@Suppress("LongMethod")
|
||||
fun LazyGridScope.stateItems() {
|
||||
sectionHeaderItem(text = "ErrorView")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
ErrorView(
|
||||
title = "Error",
|
||||
)
|
||||
}
|
||||
}
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
ErrorView(
|
||||
title = "Error with message",
|
||||
message = "Something went wrong",
|
||||
)
|
||||
}
|
||||
}
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
ErrorView(
|
||||
title = "Error with retry",
|
||||
onRetry = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
ErrorView(
|
||||
title = "Error with retry and message",
|
||||
message = "Something went wrong",
|
||||
onRetry = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "LoadingView")
|
||||
sectionSubtitleItem(text = "Default")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
LoadingView()
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With message")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
LoadingView(
|
||||
message = "Loading...",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "ContentLoadingView")
|
||||
sectionInfoItem(text = "Click below to change state")
|
||||
fullSpanItem {
|
||||
Column {
|
||||
ItemOutlinedView {
|
||||
StatefulContentLoadingView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sectionHeaderItem(text = "ContentLoadingErrorView")
|
||||
sectionInfoItem(text = "Click below to change state")
|
||||
fullSpanItem {
|
||||
Column {
|
||||
ItemOutlinedView {
|
||||
StatefulContentLoadingErrorView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StatefulContentLoadingView() {
|
||||
val state = remember {
|
||||
mutableStateOf<ContentLoadingState>(ContentLoadingState.Loading)
|
||||
}
|
||||
|
||||
ContentLoadingView(
|
||||
state = state.value,
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
when (state.value) {
|
||||
ContentLoadingState.Loading -> {
|
||||
state.value = ContentLoadingState.Content
|
||||
}
|
||||
|
||||
ContentLoadingState.Content -> {
|
||||
state.value = ContentLoadingState.Loading
|
||||
}
|
||||
}
|
||||
}
|
||||
.height(200.dp)
|
||||
.fillMaxSize(),
|
||||
loading = {
|
||||
TextTitleMedium(text = "Loading...")
|
||||
},
|
||||
content = {
|
||||
TextTitleMedium(text = "Content")
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StatefulContentLoadingErrorView() {
|
||||
val state = remember {
|
||||
mutableStateOf<ContentLoadingErrorState>(ContentLoadingErrorState.Loading)
|
||||
}
|
||||
|
||||
ContentLoadingErrorView(
|
||||
state = state.value,
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
when (state.value) {
|
||||
ContentLoadingErrorState.Loading -> {
|
||||
state.value = ContentLoadingErrorState.Content
|
||||
}
|
||||
|
||||
ContentLoadingErrorState.Content -> {
|
||||
state.value = ContentLoadingErrorState.Error
|
||||
}
|
||||
|
||||
ContentLoadingErrorState.Error -> {
|
||||
state.value = ContentLoadingErrorState.Loading
|
||||
}
|
||||
}
|
||||
}
|
||||
.height(200.dp)
|
||||
.fillMaxSize(),
|
||||
error = {
|
||||
TextTitleMedium(text = "Error")
|
||||
},
|
||||
loading = {
|
||||
TextTitleMedium(text = "Loading...")
|
||||
},
|
||||
content = {
|
||||
TextTitleMedium(text = "Content")
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract
|
||||
import net.thunderbird.ui.catalog.ui.page.common.PagedContent
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.CatalogOrganismPage.APP_BAR
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.CatalogOrganismPage.BANNER
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.CatalogOrganismPage.DIALOG
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.CatalogOrganismPage.MESSAGE_ITEM
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.CatalogOrganismPage.SNACKBAR
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.items.SnackbarItems
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.items.appBarItems
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.items.bannerItems
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.items.dialogItems
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.items.message.messageItems
|
||||
|
||||
@Composable
|
||||
fun CatalogOrganismContent(
|
||||
pages: ImmutableList<CatalogOrganismPage>,
|
||||
initialPage: CatalogOrganismPage,
|
||||
onEvent: (CatalogPageContract.Event) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
PagedContent(
|
||||
pages = pages,
|
||||
initialPage = initialPage,
|
||||
modifier = modifier,
|
||||
onRenderPage = {
|
||||
when (it) {
|
||||
APP_BAR -> appBarItems()
|
||||
DIALOG -> dialogItems()
|
||||
BANNER -> bannerItems()
|
||||
MESSAGE_ITEM -> messageItems()
|
||||
SNACKBAR -> Unit
|
||||
}
|
||||
},
|
||||
onRenderFullScreenPage = {
|
||||
when (it) {
|
||||
SNACKBAR -> SnackbarItems()
|
||||
else -> Unit
|
||||
}
|
||||
},
|
||||
onEvent = onEvent,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism
|
||||
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.CatalogPage
|
||||
|
||||
enum class CatalogOrganismPage(
|
||||
override val displayName: String,
|
||||
override val isFullScreen: Boolean = false,
|
||||
) : CatalogPage {
|
||||
APP_BAR("App Bars"),
|
||||
DIALOG("Dialogs"),
|
||||
BANNER("Banners"),
|
||||
SNACKBAR("Snackbars", isFullScreen = true),
|
||||
MESSAGE_ITEM("Message Items"),
|
||||
;
|
||||
|
||||
override fun toString(): String {
|
||||
return displayName
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun all() = entries.toImmutableList()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.common.mvi.observe
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.ViewModel
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageViewModel
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@Composable
|
||||
fun CatalogOrganismScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: ViewModel = koinViewModel<CatalogPageViewModel>(),
|
||||
) {
|
||||
val (state, dispatch) = viewModel.observe { }
|
||||
|
||||
CatalogOrganismContent(
|
||||
pages = CatalogOrganismPage.all(),
|
||||
initialPage = state.value.page as? CatalogOrganismPage ?: CatalogOrganismPage.APP_BAR,
|
||||
onEvent = { dispatch(it) },
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism.items
|
||||
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonIcon
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.SubtitleTopAppBar
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.SubtitleTopAppBarWithBackButton
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.SubtitleTopAppBarWithMenuButton
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.TopAppBar
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.TopAppBarWithBackButton
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.TopAppBarWithMenuButton
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.ItemOutlinedView
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.fullSpanItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionSubtitleItem
|
||||
|
||||
fun LazyGridScope.appBarItems() {
|
||||
topAppBarItems()
|
||||
subtitleTopAppBarItems()
|
||||
}
|
||||
|
||||
private fun LazyGridScope.topAppBarItems() {
|
||||
sectionHeaderItem(text = "TopAppBar")
|
||||
sectionSubtitleItem(text = "With menu icon")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
TopAppBar(
|
||||
title = "Title",
|
||||
actions = {
|
||||
ButtonIcon(
|
||||
onClick = {},
|
||||
imageVector = Icons.Outlined.Info,
|
||||
)
|
||||
ButtonIcon(
|
||||
onClick = {},
|
||||
imageVector = Icons.Outlined.Check,
|
||||
)
|
||||
ButtonIcon(
|
||||
onClick = {},
|
||||
imageVector = Icons.Outlined.Visibility,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With back menu icon")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
TopAppBarWithMenuButton(
|
||||
title = "Title",
|
||||
onMenuClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With back icon")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
TopAppBarWithBackButton(
|
||||
title = "Title",
|
||||
onBackClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
private fun LazyGridScope.subtitleTopAppBarItems() {
|
||||
sectionHeaderItem(text = "SubtitleTopAppBar")
|
||||
sectionSubtitleItem(text = "With menu icon")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
SubtitleTopAppBar(
|
||||
title = "Title",
|
||||
subtitle = "Subtitle",
|
||||
actions = {
|
||||
DemoActionButton(
|
||||
imageVector = Icons.Outlined.Info,
|
||||
)
|
||||
DemoActionButton(
|
||||
imageVector = Icons.Outlined.Check,
|
||||
)
|
||||
DemoActionButton(
|
||||
imageVector = Icons.Outlined.Visibility,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With long subtitle")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
SubtitleTopAppBar(
|
||||
title = "Title",
|
||||
subtitle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
|
||||
"Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
||||
actions = {
|
||||
DemoActionButton(
|
||||
imageVector = Icons.Outlined.Info,
|
||||
)
|
||||
DemoActionButton(
|
||||
imageVector = Icons.Outlined.Check,
|
||||
)
|
||||
DemoActionButton(
|
||||
imageVector = Icons.Outlined.Visibility,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With back menu icon")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
SubtitleTopAppBarWithMenuButton(
|
||||
title = "Title",
|
||||
subtitle = "Subtitle",
|
||||
onMenuClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
sectionSubtitleItem(text = "With back icon")
|
||||
fullSpanItem {
|
||||
ItemOutlinedView {
|
||||
SubtitleTopAppBarWithBackButton(
|
||||
title = "Title",
|
||||
subtitle = "Subtitle",
|
||||
onBackClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Demo action button that does nothing on click.
|
||||
*/
|
||||
@Composable
|
||||
private fun DemoActionButton(
|
||||
imageVector: ImageVector,
|
||||
) {
|
||||
ButtonIcon(
|
||||
onClick = {},
|
||||
imageVector = imageVector,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism.items
|
||||
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.items.banners.bannerGlobal
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.items.banners.bannerInline
|
||||
|
||||
fun LazyGridScope.bannerItems() {
|
||||
bannerGlobal()
|
||||
bannerInline()
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism.items
|
||||
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.items.dialogs.alertDialogs
|
||||
import net.thunderbird.ui.catalog.ui.page.organism.items.dialogs.basicDialogs
|
||||
|
||||
fun LazyGridScope.dialogItems() {
|
||||
basicDialogs()
|
||||
alertDialogs()
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism.items
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.DividerHorizontal
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonText
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.snackbar.SnackbarDuration
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.snackbar.SnackbarHost
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.snackbar.rememberSnackbarHostState
|
||||
import app.k9mail.core.ui.compose.designsystem.template.Scaffold
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun SnackbarItems(modifier: Modifier = Modifier) {
|
||||
val snackbarHostState = rememberSnackbarHostState()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
Scaffold(
|
||||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
||||
modifier = modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(it),
|
||||
) {
|
||||
SnackbarSubsection(title = "Without action") {
|
||||
ButtonText(
|
||||
text = "Show snackbar",
|
||||
onClick = {
|
||||
coroutineScope.launch {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = "Snackbar message",
|
||||
actionLabel = null,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
SnackbarSubsection(title = "With action") {
|
||||
ButtonText(
|
||||
text = "Show snackbar",
|
||||
onClick = {
|
||||
coroutineScope.launch {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = "Snackbar message",
|
||||
actionLabel = "The action",
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
SnackbarDuration.entries.forEach { duration ->
|
||||
SnackbarSubsection(title = "With ${duration.name} duration") {
|
||||
ButtonText(
|
||||
text = "Show snackbar",
|
||||
onClick = {
|
||||
coroutineScope.launch {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = "Snackbar message with ${duration.name} of duration",
|
||||
duration = duration,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SnackbarSubsection(
|
||||
title: String,
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = MainTheme.spacings.double,
|
||||
top = MainTheme.spacings.default,
|
||||
end = MainTheme.spacings.double,
|
||||
),
|
||||
) {
|
||||
TextTitleMedium(text = title)
|
||||
DividerHorizontal()
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism.items.banners
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.banner.global.ErrorBannerGlobalNotificationCard
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.banner.global.InfoBannerGlobalNotificationCard
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.banner.global.SuccessBannerGlobalNotificationCard
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.banner.global.WarningBannerGlobalNotificationCard
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.fullSpanItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionSubtitleItem
|
||||
|
||||
fun LazyGridScope.bannerGlobal() {
|
||||
sectionHeaderItem("Banner Global")
|
||||
errorBannerGlobal()
|
||||
infoBannerGlobal()
|
||||
warningBannerGlobal()
|
||||
successBannerGlobal()
|
||||
}
|
||||
|
||||
fun LazyGridScope.errorBannerGlobal() {
|
||||
sectionSubtitleItem("Error")
|
||||
fullSpanItem {
|
||||
ErrorBannerGlobalNotificationCard(
|
||||
text = "Notification Text",
|
||||
action = {
|
||||
NotificationActionButton(text = "Action 1", onClick = {})
|
||||
},
|
||||
modifier = Modifier.padding(MainTheme.spacings.double),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun LazyGridScope.infoBannerGlobal() {
|
||||
sectionSubtitleItem("Information")
|
||||
fullSpanItem {
|
||||
InfoBannerGlobalNotificationCard(
|
||||
text = "Notification Text",
|
||||
action = {
|
||||
NotificationActionButton(text = "Action 1", onClick = {})
|
||||
},
|
||||
modifier = Modifier.padding(MainTheme.spacings.double),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun LazyGridScope.warningBannerGlobal() {
|
||||
sectionSubtitleItem("Warning")
|
||||
fullSpanItem {
|
||||
WarningBannerGlobalNotificationCard(
|
||||
text = "Notification Text",
|
||||
action = {
|
||||
NotificationActionButton(text = "Action 1", onClick = {})
|
||||
},
|
||||
modifier = Modifier.padding(MainTheme.spacings.double),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun LazyGridScope.successBannerGlobal() {
|
||||
sectionSubtitleItem("Success")
|
||||
fullSpanItem {
|
||||
SuccessBannerGlobalNotificationCard(
|
||||
text = "Notification Text",
|
||||
action = {
|
||||
NotificationActionButton(text = "Action 1", onClick = {})
|
||||
},
|
||||
modifier = Modifier.padding(MainTheme.spacings.double),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism.items.banners
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.banner.inline.ErrorBannerInlineNotificationCard
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.banner.inline.InfoBannerInlineNotificationCard
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.banner.inline.SuccessBannerInlineNotificationCard
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.banner.inline.WarningBannerInlineNotificationCard
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.fullSpanItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionSubtitleItem
|
||||
|
||||
fun LazyGridScope.bannerInline() {
|
||||
sectionHeaderItem("Banner Inline")
|
||||
errorBannerInline()
|
||||
infoBannerInline()
|
||||
warningBannerInline()
|
||||
successBannerInline()
|
||||
}
|
||||
|
||||
fun LazyGridScope.errorBannerInline() {
|
||||
sectionSubtitleItem("Error")
|
||||
fullSpanItem {
|
||||
ErrorBannerInlineNotificationCard(
|
||||
title = "Notification title",
|
||||
supportingText = "Supporting text",
|
||||
actions = {
|
||||
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
|
||||
NotificationActionButton(text = "Action 1", onClick = {})
|
||||
},
|
||||
modifier = Modifier.padding(MainTheme.spacings.double),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun LazyGridScope.infoBannerInline() {
|
||||
sectionSubtitleItem("Information")
|
||||
fullSpanItem {
|
||||
InfoBannerInlineNotificationCard(
|
||||
title = "Notification title",
|
||||
supportingText = "Supporting text",
|
||||
actions = {
|
||||
NotificationActionButton(text = "Action 2", onClick = {})
|
||||
NotificationActionButton(text = "Action 1", onClick = {})
|
||||
},
|
||||
modifier = Modifier.padding(MainTheme.spacings.double),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun LazyGridScope.warningBannerInline() {
|
||||
sectionSubtitleItem("Warning")
|
||||
fullSpanItem {
|
||||
WarningBannerInlineNotificationCard(
|
||||
title = "Notification title",
|
||||
supportingText = "Supporting text",
|
||||
actions = {
|
||||
NotificationActionButton(text = "Action 2", onClick = {})
|
||||
NotificationActionButton(text = "Action 1", onClick = {})
|
||||
},
|
||||
modifier = Modifier.padding(MainTheme.spacings.double),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun LazyGridScope.successBannerInline() {
|
||||
sectionSubtitleItem("Success")
|
||||
fullSpanItem {
|
||||
SuccessBannerInlineNotificationCard(
|
||||
title = "Notification title",
|
||||
supportingText = "Supporting text",
|
||||
actions = {
|
||||
NotificationActionButton(text = "Action 2", onClick = {})
|
||||
NotificationActionButton(text = "Action 1", onClick = {})
|
||||
},
|
||||
modifier = Modifier.padding(MainTheme.spacings.double),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism.items.dialogs
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.AccountCircle
|
||||
import androidx.compose.material.icons.outlined.Info
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonFilled
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyLarge
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodySmall
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.AlertDialog
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItemPadding
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionSubtitleItem
|
||||
|
||||
internal fun LazyGridScope.alertDialogs() {
|
||||
sectionHeaderItem("Alert dialogs")
|
||||
sectionSubtitleItem("Simple dialog")
|
||||
alertDialogItem(
|
||||
title = "Simple dialog",
|
||||
text = "This is a simple dialog",
|
||||
)
|
||||
sectionSubtitleItem("Dialog with icon")
|
||||
alertDialogItem(
|
||||
icon = Icons.Outlined.Info,
|
||||
title = "Dialog with icon",
|
||||
text = "This is a dialog with icon",
|
||||
)
|
||||
sectionSubtitleItem("Dialog with cancel")
|
||||
alertDialogItem(
|
||||
icon = Icons.Outlined.AccountCircle,
|
||||
title = "Dialog with cancel",
|
||||
text = "This is a dialog with cancel",
|
||||
hasCancel = true,
|
||||
)
|
||||
sectionSubtitleItem("Dialog with custom content")
|
||||
alertDialogItem(
|
||||
title = "Dialog with custom content",
|
||||
text = "This is a dialog with custom content",
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
|
||||
) {
|
||||
TextBodyLarge("Large body")
|
||||
TextBodyMedium("Medium body")
|
||||
TextBodySmall("Small body")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.alertDialogItem(
|
||||
title: String,
|
||||
text: String,
|
||||
icon: ImageVector? = null,
|
||||
hasCancel: Boolean = false,
|
||||
content: @Composable (() -> Unit)? = null,
|
||||
) = defaultItem {
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
|
||||
ButtonFilled(
|
||||
text = "Show dialog",
|
||||
onClick = { showDialog = true },
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
|
||||
if (showDialog) {
|
||||
if (content != null) {
|
||||
AlertDialog(
|
||||
title = title,
|
||||
confirmText = "Accept",
|
||||
onConfirmClick = { showDialog = false },
|
||||
dismissText = if (hasCancel) "Cancel" else null,
|
||||
onDismissClick = { showDialog = false },
|
||||
onDismissRequest = { showDialog = false },
|
||||
) {
|
||||
content()
|
||||
}
|
||||
} else {
|
||||
AlertDialog(
|
||||
icon = icon,
|
||||
title = title,
|
||||
text = text,
|
||||
confirmText = "Accept",
|
||||
onConfirmClick = { showDialog = false },
|
||||
dismissText = if (hasCancel) "Cancel" else null,
|
||||
onDismissClick = { showDialog = false },
|
||||
onDismissRequest = { showDialog = false },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism.items.dialogs
|
||||
|
||||
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.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Refresh
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonFilled
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonText
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyLarge
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadlineSmall
|
||||
import app.k9mail.core.ui.compose.designsystem.organism.BasicDialog
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItemPadding
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionSubtitleItem
|
||||
|
||||
internal fun LazyGridScope.basicDialogs() {
|
||||
sectionHeaderItem("Basic dialogs")
|
||||
basicDialogContentAndButtonItem()
|
||||
basicDialogContentButtonHeadlineItem()
|
||||
basicDialogContentButtonHeadlineSupportingTextItem()
|
||||
basicDialogWithDividers()
|
||||
basicDialogComplexImplementation()
|
||||
}
|
||||
|
||||
private fun LazyGridScope.basicDialogContentAndButtonItem() {
|
||||
basicDialogItem(
|
||||
sectionSubtitle = "Basic Dialog with content and buttons",
|
||||
) {
|
||||
BasicDialog(
|
||||
onDismissRequest = { dismiss() },
|
||||
content = {
|
||||
TextBodyLarge("Dialog content")
|
||||
},
|
||||
buttons = { ButtonText(text = "Dismiss", onClick = { dismiss() }) },
|
||||
contentPadding = PaddingValues(horizontal = MainTheme.spacings.triple),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.basicDialogContentButtonHeadlineItem() {
|
||||
basicDialogItem(
|
||||
sectionSubtitle = "Basic Dialog with content, buttons and headline as text",
|
||||
) {
|
||||
BasicDialog(
|
||||
headlineText = "Headline text",
|
||||
onDismissRequest = { dismiss() },
|
||||
content = {
|
||||
TextBodyLarge("Dialog content")
|
||||
},
|
||||
buttons = { ButtonText(text = "Dismiss", onClick = { dismiss() }) },
|
||||
contentPadding = PaddingValues(horizontal = MainTheme.spacings.triple),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.basicDialogContentButtonHeadlineSupportingTextItem() {
|
||||
basicDialogItem(
|
||||
sectionSubtitle = "Basic Dialog with content, buttons, headline and supporting text",
|
||||
) {
|
||||
BasicDialog(
|
||||
headlineText = "Headline text",
|
||||
supportingText = "This is a supporting text",
|
||||
onDismissRequest = { dismiss() },
|
||||
content = {
|
||||
TextBodyLarge("Dialog content")
|
||||
},
|
||||
buttons = { ButtonText(text = "Dismiss", onClick = { dismiss() }) },
|
||||
contentPadding = PaddingValues(horizontal = MainTheme.spacings.triple),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.basicDialogWithDividers() {
|
||||
basicDialogItem(
|
||||
sectionSubtitle = "Basic Dialog with dividers",
|
||||
) {
|
||||
BasicDialog(
|
||||
onDismissRequest = { dismiss() },
|
||||
headlineText = "Headline text",
|
||||
supportingText = "This is a supporting text",
|
||||
content = {
|
||||
TextBodyLarge("Dialog content")
|
||||
},
|
||||
buttons = { ButtonText(text = "Dismiss", onClick = { dismiss() }) },
|
||||
contentPadding = PaddingValues(all = MainTheme.spacings.triple),
|
||||
showDividers = true,
|
||||
dividerColor = MainTheme.colors.primary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.basicDialogComplexImplementation() {
|
||||
basicDialogItem(
|
||||
sectionSubtitle = "Complex Basic dialog building",
|
||||
) {
|
||||
BasicDialog(
|
||||
onDismissRequest = { dismiss() },
|
||||
content = { ComplexBasicDialogContent() },
|
||||
buttons = {
|
||||
ButtonText(text = "Cancel", onClick = { dismiss() })
|
||||
ButtonText(text = "Accept", onClick = { dismiss() })
|
||||
},
|
||||
headline = {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
Icon(imageVector = Icons.Default.Refresh, contentDescription = null)
|
||||
TextHeadlineSmall(text = "Reset settings?")
|
||||
}
|
||||
},
|
||||
supportingText = {
|
||||
TextBodyMedium(
|
||||
text = "This will reset your app preferences back to their default settings. " +
|
||||
"The following accounts will also be signed out:",
|
||||
color = MainTheme.colors.onSurfaceVariant,
|
||||
)
|
||||
},
|
||||
showDividers = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ComplexBasicDialogContent(modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = MainTheme.spacings.triple,
|
||||
end = MainTheme.spacings.triple,
|
||||
),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(MainTheme.sizes.iconAvatar)
|
||||
.background(color = MainTheme.colors.primary, shape = CircleShape),
|
||||
)
|
||||
Text(text = "Account 1")
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(MainTheme.sizes.iconAvatar)
|
||||
.background(color = MainTheme.colors.primary, shape = CircleShape),
|
||||
)
|
||||
Text(text = "Account 2")
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(MainTheme.sizes.iconAvatar)
|
||||
.background(color = MainTheme.colors.primary, shape = CircleShape),
|
||||
)
|
||||
Text(text = "Account 3")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun LazyGridScope.basicDialogItem(
|
||||
sectionSubtitle: String,
|
||||
dialog: @Composable BasicDialogItemScope.() -> Unit,
|
||||
) {
|
||||
sectionSubtitleItem(sectionSubtitle)
|
||||
defaultItem {
|
||||
val scope = remember { BasicDialogItemScope() }
|
||||
ButtonFilled(
|
||||
text = "Show dialog",
|
||||
onClick = { scope.show() },
|
||||
modifier = Modifier.padding(defaultItemPadding()),
|
||||
)
|
||||
|
||||
if (scope.showDialog.value) {
|
||||
scope.dialog()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private interface BasicDialogItemScope {
|
||||
val showDialog: State<Boolean>
|
||||
fun show()
|
||||
fun dismiss()
|
||||
|
||||
companion object {
|
||||
operator fun invoke(): BasicDialogItemScope = object : BasicDialogItemScope {
|
||||
private val _showDialog = mutableStateOf(false)
|
||||
override val showDialog: State<Boolean> = _showDialog
|
||||
|
||||
override fun show() {
|
||||
_showDialog.value = true
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
_showDialog.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,423 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.organism.items.message
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
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.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Slider
|
||||
import androidx.compose.runtime.Composable
|
||||
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.unit.dp
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.DividerHorizontal
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextLabelSmall
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleSmall
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlined
|
||||
import app.k9mail.core.ui.compose.designsystem.molecule.input.CheckboxInput
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.random.Random
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.ExperimentalTime
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.toLocalDateTime
|
||||
import net.thunderbird.core.ui.compose.designsystem.organism.message.ActiveMessageItem
|
||||
import net.thunderbird.core.ui.compose.designsystem.organism.message.JunkMessageItem
|
||||
import net.thunderbird.core.ui.compose.designsystem.organism.message.NewMessageItem
|
||||
import net.thunderbird.core.ui.compose.designsystem.organism.message.ReadMessageItem
|
||||
import net.thunderbird.core.ui.compose.designsystem.organism.message.UnreadMessageItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.fullSpanItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionSubtitleItem
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
fun LazyGridScope.messageItems() {
|
||||
sectionHeaderItem("Message Item")
|
||||
|
||||
sectionSubtitleItem("Configuration")
|
||||
fullSpanItem {
|
||||
var config by remember {
|
||||
mutableStateOf(
|
||||
value = MessageItemConfiguration(
|
||||
sender = "Sender Name",
|
||||
subject = "The subject",
|
||||
preview = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam eleifend, leo at " +
|
||||
"elementum luctus, felis nisl placerat enim, quis aliquam erat nibh gravida eros. Nunc ac " +
|
||||
"elit mauris. Vivamus tristique, nisi eget rutrum condimentum, dui neque bibendum tortor, " +
|
||||
"id fringilla nisi sem eget velit. In euismod leo luctus, tristique ante et, vulputate " +
|
||||
"metus. Integer volutpat pulvinar dictum. Suspendisse et orci quis diam convallis accumsan " +
|
||||
"in non justo.",
|
||||
hideSection = false,
|
||||
hideAvatar = false,
|
||||
swapSenderAndSubject = false,
|
||||
randomizeAttachment = false,
|
||||
maxPreviewLines = 2,
|
||||
),
|
||||
)
|
||||
}
|
||||
Column {
|
||||
MessageItemConfiguration(
|
||||
config = config,
|
||||
onSenderChange = { config = config.copy(sender = it) },
|
||||
onSubjectChange = { config = config.copy(subject = it) },
|
||||
onPreviewChange = { config = config.copy(preview = it) },
|
||||
onHideSectionChange = { config = config.copy(hideSection = it) },
|
||||
onHideAvatarChange = { config = config.copy(hideAvatar = it) },
|
||||
onSwapSenderAndSubjectChange = { config = config.copy(swapSenderAndSubject = it) },
|
||||
onRandomizeAttachmentChange = { config = config.copy(randomizeAttachment = it) },
|
||||
onMaxPreviewLines = { config = config.copy(maxPreviewLines = it) },
|
||||
)
|
||||
DividerHorizontal(modifier = Modifier.padding(MainTheme.spacings.default))
|
||||
CatalogMessageItems(config = config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private data class MessageItemConfiguration(
|
||||
val sender: String,
|
||||
val subject: String,
|
||||
val preview: String,
|
||||
val hideSection: Boolean,
|
||||
val hideAvatar: Boolean,
|
||||
val swapSenderAndSubject: Boolean,
|
||||
val randomizeAttachment: Boolean,
|
||||
val maxPreviewLines: Int,
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun MessageItemConfiguration(
|
||||
config: MessageItemConfiguration,
|
||||
modifier: Modifier = Modifier,
|
||||
onSenderChange: (String) -> Unit = {},
|
||||
onSubjectChange: (String) -> Unit = {},
|
||||
onPreviewChange: (String) -> Unit = {},
|
||||
onHideSectionChange: (Boolean) -> Unit = {},
|
||||
onHideAvatarChange: (Boolean) -> Unit = {},
|
||||
onSwapSenderAndSubjectChange: (Boolean) -> Unit = {},
|
||||
onRandomizeAttachmentChange: (Boolean) -> Unit = {},
|
||||
onMaxPreviewLines: (Int) -> Unit = {},
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.half),
|
||||
) {
|
||||
CheckboxInput(
|
||||
text = "Hide sections",
|
||||
onCheckedChange = onHideSectionChange,
|
||||
checked = config.hideSection,
|
||||
)
|
||||
CheckboxInput(
|
||||
text = "Hide avatar",
|
||||
onCheckedChange = onHideAvatarChange,
|
||||
checked = config.hideAvatar,
|
||||
)
|
||||
CheckboxInput(
|
||||
text = "Swap sender and subject",
|
||||
onCheckedChange = onSwapSenderAndSubjectChange,
|
||||
checked = config.swapSenderAndSubject,
|
||||
)
|
||||
CheckboxInput(
|
||||
text = "Randomize attachment",
|
||||
onCheckedChange = onRandomizeAttachmentChange,
|
||||
checked = config.randomizeAttachment,
|
||||
)
|
||||
TextFieldOutlined(
|
||||
value = config.sender,
|
||||
label = "Sender",
|
||||
onValueChange = onSenderChange,
|
||||
isSingleLine = true,
|
||||
modifier = Modifier.fillMaxWidth().padding(horizontal = MainTheme.spacings.double),
|
||||
)
|
||||
TextFieldOutlined(
|
||||
value = config.subject,
|
||||
label = "Subject",
|
||||
onValueChange = onSubjectChange,
|
||||
isSingleLine = true,
|
||||
modifier = Modifier.fillMaxWidth().padding(horizontal = MainTheme.spacings.double),
|
||||
)
|
||||
TextFieldOutlined(
|
||||
value = config.preview,
|
||||
label = "Preview",
|
||||
onValueChange = onPreviewChange,
|
||||
isSingleLine = false,
|
||||
modifier = Modifier.fillMaxWidth().padding(horizontal = MainTheme.spacings.double),
|
||||
)
|
||||
Column(modifier = Modifier.padding(horizontal = MainTheme.spacings.double)) {
|
||||
TextLabelSmall(text = "Preview lines: ${config.maxPreviewLines}")
|
||||
Slider(
|
||||
value = config.maxPreviewLines.toFloat(),
|
||||
onValueChange = { onMaxPreviewLines(it.roundToInt()) },
|
||||
valueRange = 1f..6f,
|
||||
steps = 6,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CatalogMessageItems(config: MessageItemConfiguration, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
CatalogNewMessageItem(config = config)
|
||||
CatalogUnreadMessageItem(config = config)
|
||||
CatalogReadMessageItem(config = config)
|
||||
CatalogActiveMessageItem(config = config)
|
||||
CatalogJunkMessageItem(config = config)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.CatalogNewMessageItem(config: MessageItemConfiguration) {
|
||||
if (!config.hideSection) {
|
||||
Section(text = "New Message", modifier = Modifier.padding(vertical = MainTheme.spacings.double))
|
||||
}
|
||||
var selected by remember { mutableStateOf(false) }
|
||||
var favourite by remember { mutableStateOf(false) }
|
||||
NewMessageItem(
|
||||
sender = config.sender,
|
||||
subject = config.subject,
|
||||
preview = config.preview,
|
||||
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now()
|
||||
.toLocalDateTime(TimeZone.currentSystemDefault()),
|
||||
favourite = favourite,
|
||||
avatar = {
|
||||
if (!config.hideAvatar) {
|
||||
Avatar(
|
||||
sender = config.sender,
|
||||
enabled = !selected,
|
||||
onClick = { selected = true },
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
if (selected) {
|
||||
selected = false
|
||||
}
|
||||
},
|
||||
onFavouriteChange = { favourite = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
selected = selected,
|
||||
swapSenderWithSubject = config.swapSenderAndSubject,
|
||||
hasAttachments = remember(config.randomizeAttachment) {
|
||||
if (config.randomizeAttachment) Random.nextBoolean() else false
|
||||
},
|
||||
maxPreviewLines = config.maxPreviewLines,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.CatalogUnreadMessageItem(config: MessageItemConfiguration) {
|
||||
if (!config.hideSection) {
|
||||
Section(text = "Unread Message", modifier = Modifier.padding(vertical = MainTheme.spacings.double))
|
||||
}
|
||||
var selected by remember { mutableStateOf(false) }
|
||||
var favourite by remember { mutableStateOf(false) }
|
||||
UnreadMessageItem(
|
||||
sender = config.sender,
|
||||
subject = config.subject,
|
||||
preview = config.preview,
|
||||
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now()
|
||||
.toLocalDateTime(TimeZone.currentSystemDefault()),
|
||||
favourite = favourite,
|
||||
avatar = {
|
||||
if (!config.hideAvatar) {
|
||||
Avatar(
|
||||
sender = config.sender,
|
||||
enabled = !selected,
|
||||
onClick = { selected = true },
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
if (selected) {
|
||||
selected = false
|
||||
}
|
||||
},
|
||||
onFavouriteChange = { favourite = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
selected = selected,
|
||||
swapSenderWithSubject = config.swapSenderAndSubject,
|
||||
hasAttachments = remember(config.randomizeAttachment) {
|
||||
if (config.randomizeAttachment) Random.nextBoolean() else false
|
||||
},
|
||||
maxPreviewLines = config.maxPreviewLines,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.CatalogReadMessageItem(config: MessageItemConfiguration) {
|
||||
if (!config.hideSection) {
|
||||
Section(text = "Read Message", modifier = Modifier.padding(vertical = MainTheme.spacings.double))
|
||||
}
|
||||
var selected by remember { mutableStateOf(false) }
|
||||
var favourite by remember { mutableStateOf(false) }
|
||||
ReadMessageItem(
|
||||
sender = config.sender,
|
||||
subject = config.subject,
|
||||
preview = config.preview,
|
||||
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now()
|
||||
.toLocalDateTime(TimeZone.currentSystemDefault()),
|
||||
favourite = favourite,
|
||||
avatar = {
|
||||
if (!config.hideAvatar) {
|
||||
Avatar(
|
||||
sender = config.sender,
|
||||
enabled = !selected,
|
||||
onClick = { selected = true },
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
if (selected) {
|
||||
selected = false
|
||||
}
|
||||
},
|
||||
onFavouriteChange = { favourite = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
selected = selected,
|
||||
swapSenderWithSubject = config.swapSenderAndSubject,
|
||||
hasAttachments = remember(config.randomizeAttachment) {
|
||||
if (config.randomizeAttachment) Random.nextBoolean() else false
|
||||
},
|
||||
maxPreviewLines = config.maxPreviewLines,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.CatalogActiveMessageItem(config: MessageItemConfiguration) {
|
||||
if (!config.hideSection) {
|
||||
Section(text = "Active Message", modifier = Modifier.padding(vertical = MainTheme.spacings.double))
|
||||
}
|
||||
var selected by remember { mutableStateOf(false) }
|
||||
var favourite by remember { mutableStateOf(false) }
|
||||
ActiveMessageItem(
|
||||
sender = config.sender,
|
||||
subject = config.subject,
|
||||
preview = config.preview,
|
||||
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now()
|
||||
.toLocalDateTime(TimeZone.currentSystemDefault()),
|
||||
favourite = favourite,
|
||||
avatar = {
|
||||
if (!config.hideAvatar) {
|
||||
Avatar(
|
||||
sender = config.sender,
|
||||
enabled = !selected,
|
||||
onClick = { selected = true },
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
if (selected) {
|
||||
selected = false
|
||||
}
|
||||
},
|
||||
onFavouriteChange = { favourite = it },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
selected = selected,
|
||||
swapSenderWithSubject = config.swapSenderAndSubject,
|
||||
hasAttachments = remember(config.randomizeAttachment) {
|
||||
if (config.randomizeAttachment) Random.nextBoolean() else false
|
||||
},
|
||||
maxPreviewLines = config.maxPreviewLines,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.CatalogJunkMessageItem(config: MessageItemConfiguration) {
|
||||
if (!config.hideSection) {
|
||||
Section(text = "Junk Message", modifier = Modifier.padding(vertical = MainTheme.spacings.double))
|
||||
}
|
||||
var selected by remember { mutableStateOf(false) }
|
||||
JunkMessageItem(
|
||||
sender = config.sender,
|
||||
subject = config.subject,
|
||||
preview = config.preview,
|
||||
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now()
|
||||
.toLocalDateTime(TimeZone.currentSystemDefault()),
|
||||
avatar = {
|
||||
if (!config.hideAvatar) {
|
||||
Avatar(
|
||||
sender = config.sender,
|
||||
enabled = !selected,
|
||||
onClick = { selected = true },
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = {
|
||||
if (selected) {
|
||||
selected = false
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
selected = selected,
|
||||
swapSenderWithSubject = config.swapSenderAndSubject,
|
||||
hasAttachments = remember(config.randomizeAttachment) {
|
||||
if (config.randomizeAttachment) Random.nextBoolean() else false
|
||||
},
|
||||
maxPreviewLines = config.maxPreviewLines,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Section(text: String, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = MainTheme.spacings.double,
|
||||
top = MainTheme.spacings.default,
|
||||
end = MainTheme.spacings.double,
|
||||
),
|
||||
) {
|
||||
TextTitleMedium(
|
||||
text = text,
|
||||
)
|
||||
DividerHorizontal()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Avatar(
|
||||
sender: String,
|
||||
enabled: Boolean,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(MainTheme.sizes.iconAvatar)
|
||||
.clip(CircleShape)
|
||||
.clickable(enabled = enabled, onClick = onClick)
|
||||
.padding(MainTheme.spacings.half)
|
||||
.background(
|
||||
color = MainTheme.colors.primaryContainer.copy(alpha = 0.15f),
|
||||
shape = CircleShape,
|
||||
)
|
||||
.border(width = 1.dp, color = MainTheme.colors.primary, shape = CircleShape),
|
||||
) {
|
||||
val monogram = remember(sender) {
|
||||
val parts = sender.split(" ")
|
||||
buildString {
|
||||
append(parts.first().first())
|
||||
if (parts.size > 1) {
|
||||
append(parts.last().first())
|
||||
}
|
||||
}
|
||||
}
|
||||
TextTitleSmall(text = monogram, modifier = Modifier.align(Alignment.Center))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.template
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract
|
||||
import net.thunderbird.ui.catalog.ui.page.common.PagedContent
|
||||
import net.thunderbird.ui.catalog.ui.page.template.CatalogTemplatePage.LAYOUT
|
||||
import net.thunderbird.ui.catalog.ui.page.template.items.layoutItems
|
||||
|
||||
@Composable
|
||||
fun CatalogTemplateContent(
|
||||
pages: ImmutableList<CatalogTemplatePage>,
|
||||
initialPage: CatalogTemplatePage,
|
||||
onEvent: (CatalogPageContract.Event) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
PagedContent(
|
||||
pages = pages,
|
||||
initialPage = initialPage,
|
||||
modifier = modifier,
|
||||
onRenderPage = {
|
||||
when (it) {
|
||||
LAYOUT -> layoutItems()
|
||||
}
|
||||
},
|
||||
onRenderFullScreenPage = {},
|
||||
onEvent = onEvent,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.template
|
||||
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.CatalogPage
|
||||
|
||||
enum class CatalogTemplatePage(
|
||||
override val displayName: String,
|
||||
override val isFullScreen: Boolean = false,
|
||||
) : CatalogPage {
|
||||
LAYOUT("Layouts"),
|
||||
;
|
||||
|
||||
override fun toString(): String {
|
||||
return displayName
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun all() = entries.toImmutableList()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.template
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.common.mvi.observe
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageContract.ViewModel
|
||||
import net.thunderbird.ui.catalog.ui.page.CatalogPageViewModel
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@Composable
|
||||
fun CatalogTemplateScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: ViewModel = koinViewModel<CatalogPageViewModel>(),
|
||||
) {
|
||||
val (state, dispatch) = viewModel.observe { }
|
||||
|
||||
CatalogTemplateContent(
|
||||
pages = CatalogTemplatePage.Companion.all(),
|
||||
initialPage = state.value.page as? CatalogTemplatePage ?: CatalogTemplatePage.LAYOUT,
|
||||
onEvent = { dispatch(it) },
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
package net.thunderbird.ui.catalog.ui.page.template.items
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.Surface
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyLarge
|
||||
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
|
||||
import app.k9mail.core.ui.compose.designsystem.template.ListDetailPane
|
||||
import app.k9mail.core.ui.compose.designsystem.template.rememberListDetailNavigationController
|
||||
import app.k9mail.core.ui.compose.theme2.MainTheme
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.defaultItem
|
||||
import net.thunderbird.ui.catalog.ui.page.common.list.sectionHeaderItem
|
||||
|
||||
fun LazyGridScope.layoutItems() {
|
||||
sectionHeaderItem(text = "ListDetailPane")
|
||||
defaultItem {
|
||||
ListDetailPaneItem()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ListDetailPaneItem() {
|
||||
val navigationController = rememberListDetailNavigationController<ListItem>()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(MainTheme.sizes.huger)
|
||||
.padding(MainTheme.spacings.double),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
ListDetailPane(
|
||||
navigationController = navigationController,
|
||||
listPane = {
|
||||
Surface(
|
||||
color = MainTheme.colors.primaryContainer,
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
|
||||
) {
|
||||
TextTitleMedium("List pane")
|
||||
LazyColumn(
|
||||
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
|
||||
) {
|
||||
itemsIndexed(createItems()) { index, item ->
|
||||
ListItem(
|
||||
item = item,
|
||||
onClick = {
|
||||
coroutineScope.launch {
|
||||
navigationController.value.navigateToDetail(item)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
detailPane = { item ->
|
||||
Surface(
|
||||
color = MainTheme.colors.secondaryContainer,
|
||||
) {
|
||||
ListDetail(
|
||||
item = item,
|
||||
onClick = {
|
||||
coroutineScope.launch {
|
||||
navigationController.value.navigateBack()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ListItem(
|
||||
item: ListItem,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable(onClick = onClick)
|
||||
.fillMaxWidth()
|
||||
.padding(MainTheme.spacings.default),
|
||||
) {
|
||||
TextBodyLarge(item.title)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ListDetail(
|
||||
item: ListItem,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable(onClick = onClick)
|
||||
.fillMaxWidth()
|
||||
.padding(MainTheme.spacings.default),
|
||||
) {
|
||||
TextTitleMedium("Detail pane")
|
||||
Spacer(modifier = Modifier.height(MainTheme.spacings.default))
|
||||
TextBodyLarge(item.title)
|
||||
}
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
internal data class ListItem(
|
||||
val id: String,
|
||||
val title: String,
|
||||
) : Parcelable
|
||||
|
||||
private fun createItems(): List<ListItem> {
|
||||
return listOf(
|
||||
ListItem(
|
||||
id = "1",
|
||||
title = "Item 1",
|
||||
),
|
||||
ListItem(
|
||||
id = "2",
|
||||
title = "Item 2",
|
||||
),
|
||||
ListItem(
|
||||
id = "3",
|
||||
title = "Item 3",
|
||||
),
|
||||
)
|
||||
}
|
||||
164
app-ui-catalog/src/main/res/drawable/ic_app_logo.xml
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="1024dp"
|
||||
android:height="1024dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M439.5,260.2L439.6,260.2C466.3,167 582.5,121.5 700.9,121.5C782.7,121.5 856.2,147.4 906.5,188.5C875.3,190.1 845.7,196.2 818.5,206C859.2,221.1 894.2,244.4 920.1,273.2C902.9,270.2 885,268.7 866.8,268.7C864.8,268.7 862.8,268.7 860.9,268.7C907.9,337 935.5,419.7 935.5,508.9C935.5,742.8 745.9,932.4 512,932.4C281.7,932.4 88.5,739.5 88.5,508.9C88.5,472.4 93.3,434.8 102.7,399.5C105.2,392.1 108.6,385 113.2,382.4C118.9,379.2 124.1,388.9 125,392C131.2,415.3 139.5,437.9 149.8,459.5C148.9,411.1 169.6,367.1 198,329C217,303.6 234.5,280 242.6,212.1C243.2,207.6 247.5,204.3 251.9,205.7C313.5,225.9 346.5,328.6 341.4,414.4C375.4,419.3 375.3,383.7 375.3,383.7C364.4,350.2 371.6,288 439.4,260.2L439.5,260.2Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="396.6"
|
||||
android:startY="288.4"
|
||||
android:endX="832.5"
|
||||
android:endY="817.9"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF88CCFC"/>
|
||||
<item android:offset="1" android:color="#FF590DF2"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M921.6,401C931.9,633.9 740.5,834.8 507,834.8C288.4,834.8 109.3,665.8 93.1,451.4C90.2,471.2 88.7,491.4 88.5,512C90.2,741.5 282.9,932.4 512,932.4C745.9,932.4 935.5,742.8 935.5,508.9C935.5,471.6 930.7,435.5 921.6,401Z"
|
||||
android:strokeAlpha="0.9"
|
||||
android:fillAlpha="0.9">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:centerX="234.4"
|
||||
android:centerY="452.7"
|
||||
android:gradientRadius="358.1"
|
||||
android:type="radial">
|
||||
<item android:offset="0.5" android:color="#000B4186"/>
|
||||
<item android:offset="1" android:color="#720B4186"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M502.2,291.3C497.6,283.2 476.5,271.3 467.3,269.2C502.2,157.6 679.7,123.3 788.4,143C833.6,151.3 889.9,175.9 907,188.7C856.7,147.6 783.2,121.7 701.4,121.7C583,121.7 466.7,167.2 440.1,260.4L440,260.4L439.9,260.4C372.1,288.2 364.9,350.5 375.8,383.9C386.2,344 436,295 502.2,291.3Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="587.8"
|
||||
android:startY="332.8"
|
||||
android:endX="442.3"
|
||||
android:endY="231"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#00D13AEF"/>
|
||||
<item android:offset="1" android:color="#E5F9D286"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M624.7,214C529.6,232.7 498.5,238.8 466.7,269.1C502.4,174.4 593.7,155.3 702.5,198.4C672.5,204.6 646.9,209.6 624.7,214Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="307.2"
|
||||
android:startY="473.7"
|
||||
android:endX="616.4"
|
||||
android:endY="164.5"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF450FB0"/>
|
||||
<item android:offset="0.8" android:color="#1E4610B1"/>
|
||||
<item android:offset="1" android:color="#00450FB0"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M111.5,386.6C85.5,493 105.6,618 223.7,723C188.5,684.6 145.6,542.6 240.3,441.2C246.7,434.4 257.6,439.4 258,448.8C265.8,659.5 435.8,788.2 631.9,764.1C571.1,760.7 370.3,690.4 519.7,662.5C597.8,648 720.3,625.2 720.3,515.3C720.3,337.1 582.5,285 499,292.8C441.8,298.1 391,334.4 375.3,383.7C381.3,403.1 357.4,416.8 341.4,414.5C346.5,328.6 313.5,225.9 251.9,205.7C247.5,204.3 243.2,207.6 242.6,212.1C234.5,280 217,303.6 198,329C169.6,367.1 148.9,411.1 149.8,459.5C139.5,437.9 131.2,415.3 125,392C124.3,389.4 120.5,382.1 115.9,381.8C113.4,381.6 112.1,384 111.5,386.6Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:centerX="352.3"
|
||||
android:centerY="739.6"
|
||||
android:gradientRadius="558.7"
|
||||
android:type="radial">
|
||||
<item android:offset="0" android:color="#FF650877"/>
|
||||
<item android:offset="1" android:color="#00340B86"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M467.2,673.3C582.2,766.7 813.5,696.7 813.5,469.6C720.1,611.2 601.2,708.8 467.2,673.3Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="778.1"
|
||||
android:startY="576.8"
|
||||
android:endX="630.1"
|
||||
android:endY="762.5"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#00D647E2"/>
|
||||
<item android:offset="1" android:color="#A3E7BB65"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M240.3,441.2C242.7,438.6 245.8,437.7 248.7,438.1C164,541.5 232.3,723.1 279.3,767.7C281.9,775.1 234.8,736.5 228.3,727.5C192.6,697.2 141.4,547.1 240.3,441.2Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="173.2"
|
||||
android:startY="429.1"
|
||||
android:endX="241.4"
|
||||
android:endY="712.5"
|
||||
android:type="linear">
|
||||
<item android:offset="0.1" android:color="#FFF9BF86"/>
|
||||
<item android:offset="1" android:color="#00D63AEF"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M512,681.9C627,681.9 720.3,605.8 720.3,511.9C720.3,418.1 627,342 512,342C413.9,342 303.7,405.8 303.7,514.4C303.8,682.2 481,778.7 632.1,764.1C620.8,762.8 550,759 502.1,704.9C497.8,700 490.3,691.5 493.7,686C497.1,680.4 506.5,681.9 512,681.9Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="512"
|
||||
android:startY="404.2"
|
||||
android:endX="512"
|
||||
android:endY="762.4"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FFFFFFFF"/>
|
||||
<item android:offset="0.9" android:color="#FFBEE1FE"/>
|
||||
<item android:offset="1" android:color="#FF96CEFD"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M541.2,257C563.5,249.9 561.6,227.9 561.6,227.9C561.6,227.9 550.4,214.8 528.3,222C507.7,228.8 504.4,243.6 504.4,243.6C504.4,243.6 515.7,265 541.2,257Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M512.5,440.5C465.2,423.4 438.7,420.8 391.5,440.5V582C438.7,567 465.3,566.7 512.5,582C564,573.1 589.7,572.9 629,582V440.5C586.8,424 560.8,426.3 512.5,440.5Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="510.3"
|
||||
android:startY="426.7"
|
||||
android:endX="510.3"
|
||||
android:endY="582"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#A3BCE0FD"/>
|
||||
<item android:offset="1" android:color="#00D647E2"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M445,561.3C454.5,561.3 463.8,562.3 472.9,564.4C481.9,566.6 490.9,569.8 499.8,574V454C491.5,449.1 482.7,445.5 473.3,443C464,440.6 454.5,439.4 445,439.4C437.7,439.4 430.4,440.1 423.2,441.5C416,442.9 409.1,445.1 402.4,447.9V568.6C409.5,566.1 416.5,564.3 423.5,563.1C430.5,561.9 437.7,561.3 445,561.3ZM524.2,574C533.1,569.8 542.1,566.6 551.1,564.4C560.2,562.3 569.5,561.3 579,561.3C586.3,561.3 593.5,561.9 600.5,563.1C607.5,564.3 614.5,566.1 621.6,568.6V447.9C614.9,445.1 608,442.9 600.8,441.5C593.6,440.1 586.3,439.4 579,439.4C569.5,439.4 560,440.6 550.7,443C541.3,445.5 532.5,449.1 524.2,454V574ZM512,610C502.3,602.3 491.7,596.3 480.3,592C469,587.8 457.2,585.6 445,585.6C436.5,585.6 428.1,586.7 419.9,589C411.7,591.2 403.8,594.4 396.3,598.4C392,600.7 387.9,600.6 383.9,598.1C380,595.7 378,592.1 378,587.5V440.6C378,438.4 378.6,436.2 379.7,434.2C380.8,432.2 382.5,430.6 384.7,429.6C394,424.8 403.8,421.1 413.9,418.7C424.1,416.2 434.4,415 445,415C456.8,415 468.3,416.5 479.6,419.6C490.8,422.6 501.6,427.2 512,433.3C522.4,427.2 533.2,422.6 544.4,419.6C555.7,416.5 567.2,415 579,415C589.6,415 599.9,416.2 610.1,418.7C620.2,421.1 630,424.8 639.3,429.6C641.5,430.6 643.2,432.2 644.3,434.2C645.4,436.2 646,438.4 646,440.6V587.5C646,592.1 644,595.7 640.1,598.1C636.1,600.6 632,600.7 627.7,598.4C620.2,594.4 612.3,591.2 604.1,589C595.9,586.7 587.5,585.6 579,585.6C566.8,585.6 555,587.8 543.7,592C532.3,596.3 521.7,602.3 512,610Z"
|
||||
android:fillColor="#0768BA"
|
||||
android:fillAlpha="0.3"/>
|
||||
<path
|
||||
android:pathData="M414.5,539.6H428.3L435.3,519.5H466.9L474.2,539.6H487.6L458.1,461H444.1L414.5,539.6ZM439.2,508.2L450.8,475.6H451.4L463,508.2H439.2ZM536.4,486.9V466.2C543.1,463.3 549.9,461.2 556.9,459.8C563.9,458.4 571.3,457.7 579,457.7C584.3,457.7 589.5,458.1 594.5,458.9C599.6,459.7 604.6,460.7 609.5,461.9V481.4C604.6,479.6 599.7,478.2 594.7,477.3C589.7,476.4 584.5,475.9 579,475.9C571.3,475.9 563.9,476.9 556.8,478.8C549.7,480.8 542.9,483.5 536.4,486.9ZM536.4,553.9V533.2C543.1,530.4 549.9,528.2 556.9,526.8C563.9,525.4 571.3,524.7 579,524.7C584.3,524.7 589.5,525.1 594.5,525.9C599.6,526.7 604.6,527.7 609.5,529V548.5C604.6,546.6 599.7,545.3 594.7,544.3C589.7,543.4 584.5,543 579,543C571.3,543 563.9,543.9 556.8,545.7C549.7,547.5 542.9,550.3 536.4,553.9ZM536.4,520.4V499.7C543.1,496.9 549.9,494.7 556.9,493.3C563.9,491.9 571.3,491.2 579,491.2C584.3,491.2 589.5,491.6 594.5,492.4C599.6,493.2 604.6,494.2 609.5,495.4V514.9C604.6,513.1 599.7,511.7 594.7,510.8C589.7,509.9 584.5,509.5 579,509.5C571.3,509.5 563.9,510.4 556.8,512.3C549.7,514.3 542.9,517 536.4,520.4ZM445,561.3C454.5,561.3 463.8,562.3 472.9,564.4C481.9,566.6 490.9,569.8 499.8,574V454C491.5,449.1 482.7,445.5 473.3,443C464,440.6 454.5,439.4 445,439.4C437.7,439.4 430.4,440.1 423.2,441.5C416,442.9 409.1,445.1 402.4,447.9V568.6C409.5,566.1 416.5,564.3 423.5,563.1C430.5,561.9 437.7,561.3 445,561.3ZM524.2,574C533.1,569.8 542.1,566.6 551.1,564.4C560.2,562.3 569.5,561.3 579,561.3C586.3,561.3 593.5,561.9 600.5,563.1C607.5,564.3 614.5,566.1 621.6,568.6V447.9C614.9,445.1 608,442.9 600.8,441.5C593.6,440.1 586.3,439.4 579,439.4C569.5,439.4 560,440.6 550.7,443C541.3,445.5 532.5,449.1 524.2,454V574ZM512,610C502.3,602.3 491.7,596.3 480.3,592C469,587.8 457.2,585.6 445,585.6C436.5,585.6 428.1,586.7 419.9,589C411.7,591.2 403.8,594.4 396.3,598.4C392,600.7 387.9,600.6 383.9,598.1C380,595.7 378,592.1 378,587.5V440.6C378,438.4 378.6,436.2 379.7,434.2C380.8,432.2 382.5,430.6 384.7,429.6C394,424.8 403.8,421.1 413.9,418.7C424.1,416.2 434.4,415 445,415C456.8,415 468.3,416.5 479.6,419.6C490.8,422.6 501.6,427.2 512,433.3C522.4,427.2 533.2,422.6 544.4,419.6C555.7,416.5 567.2,415 579,415C589.6,415 599.9,416.2 610.1,418.7C620.2,421.1 630,424.8 639.3,429.6C641.5,430.6 643.2,432.2 644.3,434.2C645.4,436.2 646,438.4 646,440.6V587.5C646,592.1 644,595.7 640.1,598.1C636.1,600.6 632,600.7 627.7,598.4C620.2,594.4 612.3,591.2 604.1,589C595.9,586.7 587.5,585.6 579,585.6C566.8,585.6 555,587.8 543.7,592C532.3,596.3 521.7,602.3 512,610Z"
|
||||
android:fillAlpha="0.9">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="472"
|
||||
android:startY="430"
|
||||
android:endX="555.5"
|
||||
android:endY="629"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF590DF2"/>
|
||||
<item android:offset="0.5" android:color="#FF1373D9"/>
|
||||
<item android:offset="1" android:color="#FFEF3ACC"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M435.3,517.5H433.8L433.4,518.8L426.8,537.6H417.4L445.5,463H456.7L484.7,537.6H475.6L468.8,518.8L468.3,517.5H466.9H435.3ZM437.3,507.6L436.4,510.2H439.2H463H465.8L464.9,507.6L453.3,475L452.8,473.6H451.4H450.8H449.4L448.9,475L437.3,507.6ZM499,575.9L501.8,577.2V574V454V452.9L500.8,452.3C492.3,447.3 483.3,443.6 473.8,441.1C464.3,438.6 454.7,437.4 445,437.4C437.6,437.4 430.2,438.1 422.8,439.5C415.5,441 408.4,443.2 401.6,446.1L400.4,446.6V447.9V568.6V571.4L403,570.5C410,568 417,566.2 423.9,565C430.8,563.8 437.8,563.3 445,563.3C454.4,563.3 463.5,564.3 472.4,566.4C481.3,568.5 490.1,571.6 499,575.9ZM522.2,574V577.2L525,575.9C533.9,571.6 542.7,568.5 551.6,566.4C560.5,564.3 569.6,563.3 579,563.3C586.2,563.3 593.2,563.8 600.1,565C607,566.2 614,568 621,570.5L623.6,571.4V568.6V447.9V446.6L622.4,446.1C615.6,443.2 608.5,441 601.2,439.5C593.8,438.1 586.4,437.4 579,437.4C569.3,437.4 559.7,438.6 550.2,441.1C540.7,443.6 531.7,447.3 523.2,452.3L522.2,452.9V454V574ZM385.5,431.4L385.6,431.4L385.6,431.4C394.8,426.6 404.4,423 414.4,420.6C424.4,418.2 434.6,417 445,417C456.6,417 467.9,418.5 479,421.5C490.1,424.5 500.8,429 511,435L512,435.6L513,435C523.2,429 533.9,424.5 545,421.5C556.1,418.5 567.4,417 579,417C589.4,417 599.6,418.2 609.6,420.6C619.6,423 629.2,426.6 638.4,431.4L638.4,431.4L638.5,431.4C640.3,432.3 641.7,433.5 642.6,435.2C643.5,436.9 644,438.7 644,440.6V587.5C644,591.4 642.4,594.3 639,596.4C635.7,598.5 632.3,598.6 628.7,596.7C621,592.5 613,589.3 604.6,587C596.3,584.8 587.7,583.6 579,583.6C566.6,583.6 554.6,585.8 543,590.2C531.9,594.3 521.6,600.1 512,607.5C502.4,600.1 492.1,594.3 481,590.2C469.4,585.8 457.4,583.6 445,583.6C436.3,583.6 427.7,584.8 419.4,587C411,589.3 403,592.5 395.3,596.7C391.7,598.6 388.3,598.5 385,596.4C381.6,594.3 380,591.4 380,587.5V440.6C380,438.7 380.5,436.9 381.4,435.2C382.3,433.5 383.7,432.3 385.5,431.4ZM607.5,463.5V478.6C603.4,477.2 599.2,476.1 595,475.3C589.9,474.4 584.6,473.9 579,473.9C571.1,473.9 563.5,474.9 556.2,476.9C550.1,478.6 544.1,480.8 538.4,483.6V467.5C544.6,465 550.9,463.1 557.3,461.7C564.2,460.4 571.4,459.7 579,459.7C584.2,459.7 589.2,460.1 594.2,460.9C598.7,461.6 603.1,462.5 607.5,463.5ZM607.5,530.5V545.6C603.4,544.2 599.2,543.1 595,542.4C589.9,541.4 584.6,541 579,541C571.1,541 563.5,541.9 556.3,543.8C550.1,545.4 544.1,547.6 538.4,550.6V534.6C544.6,532 550.9,530.1 557.3,528.8C564.2,527.4 571.4,526.7 579,526.7C584.2,526.7 589.2,527.1 594.2,527.9C598.7,528.6 603.1,529.5 607.5,530.5ZM607.5,497V512.1C603.4,510.7 599.2,509.6 595,508.9C589.9,507.9 584.6,507.5 579,507.5C571.1,507.5 563.5,508.4 556.2,510.4C550.1,512.1 544.1,514.3 538.4,517.2V501C544.6,498.5 550.9,496.6 557.3,495.3C564.2,493.9 571.4,493.2 579,493.2C584.2,493.2 589.2,493.6 594.2,494.4C598.7,495.1 603.1,496 607.5,497Z"
|
||||
android:strokeAlpha="0.2"
|
||||
android:strokeWidth="4"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#0768BA"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="1024dp"
|
||||
android:height="1024dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M440.1,249.7L440,249.7L439.9,249.7C372.1,277.6 364.9,339.8 375.8,373.2C375.8,373.2 375.8,373.5 375.8,374C415,346.4 465.1,331.5 512.5,331.5C627.5,331.5 720.8,407.6 720.8,501.4C720.8,595.3 627.5,671.4 512.5,671.4C511.6,671.4 510.6,671.4 509.6,671.3L509.6,671.3C504.1,671.1 497.1,670.8 494.2,675.5C490.8,681 498.3,689.5 502.6,694.4C547.6,745.3 612.8,751.7 630,753.4C631.1,753.5 632,753.6 632.6,753.6C481.5,768.3 304.3,671.7 304.2,503.9C304.2,464.4 318.8,430.8 342.1,404C342,404 342,404 341.9,404C347,318.1 314,215.4 252.4,195.2C248,193.8 243.7,197.1 243.1,201.6C235,269.6 217.5,293.1 198.5,318.5C170.1,356.6 149.4,400.6 150.3,449C140,427.4 131.7,404.9 125.5,381.6C124.6,378.4 119.4,368.7 113.7,372C109.1,374.6 105.7,381.7 103.2,389.1C93.8,424.3 89,462 89,498.4C89,729.1 282.2,921.9 512.5,921.9C746.4,921.9 936,732.3 936,498.4C936,409.2 908.4,326.5 861.4,258.2C863.3,258.2 865.3,258.2 867.3,258.2C885.5,258.2 903.4,259.7 920.6,262.7C894.7,233.9 859.7,210.7 819,195.5C846.2,185.7 875.8,179.6 907,178C856.7,136.9 783.2,111 701.4,111C583,111 466.8,156.5 440.1,249.7ZM562.1,217.4C562.1,217.4 564,239.5 541.7,246.5C516.2,254.5 504.9,233.1 504.9,233.1C504.9,233.1 508.2,218.4 528.8,211.6C550.9,204.3 562.1,217.4 562.1,217.4Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M414.5,543.6H428.3L435.3,523.5H466.9L474.2,543.6H487.6L458.1,465H444.1L414.5,543.6ZM439.2,512.2L450.8,479.6H451.4L463,512.2H439.2ZM536.4,490.9V470.2C543.1,467.3 549.9,465.2 556.9,463.8C563.9,462.4 571.3,461.7 579,461.7C584.3,461.7 589.5,462.1 594.5,462.9C599.6,463.7 604.6,464.7 609.5,465.9V485.4C604.6,483.6 599.7,482.2 594.7,481.3C589.7,480.4 584.5,479.9 579,479.9C571.3,479.9 563.9,480.9 556.8,482.8C549.7,484.8 542.9,487.5 536.4,490.9ZM536.4,557.9V537.2C543.1,534.4 549.9,532.2 556.9,530.8C563.9,529.4 571.3,528.7 579,528.7C584.3,528.7 589.5,529.1 594.5,529.9C599.6,530.7 604.6,531.7 609.5,533V552.5C604.6,550.6 599.7,549.3 594.7,548.3C589.7,547.4 584.5,547 579,547C571.3,547 563.9,547.9 556.8,549.7C549.7,551.5 542.9,554.3 536.4,557.9ZM536.4,524.4V503.7C543.1,500.9 549.9,498.7 556.9,497.3C563.9,495.9 571.3,495.2 579,495.2C584.3,495.2 589.5,495.6 594.5,496.4C599.6,497.2 604.6,498.2 609.5,499.4V518.9C604.6,517.1 599.7,515.7 594.7,514.8C589.7,513.9 584.5,513.5 579,513.5C571.3,513.5 563.9,514.4 556.8,516.3C549.7,518.3 542.9,521 536.4,524.4ZM445,565.3C454.5,565.3 463.8,566.3 472.9,568.4C481.9,570.6 490.9,573.8 499.8,578V458C491.5,453.1 482.7,449.5 473.3,447C464,444.6 454.5,443.4 445,443.4C437.7,443.4 430.4,444.1 423.2,445.5C416,446.9 409.1,449.1 402.4,451.9V572.6C409.5,570.1 416.5,568.3 423.5,567.1C430.5,565.9 437.7,565.3 445,565.3ZM524.2,578C533.1,573.8 542.1,570.6 551.1,568.4C560.2,566.3 569.5,565.3 579,565.3C586.3,565.3 593.5,565.9 600.5,567.1C607.5,568.3 614.5,570.1 621.6,572.6V451.9C614.9,449.1 608,446.9 600.8,445.5C593.6,444.1 586.3,443.4 579,443.4C569.5,443.4 560,444.6 550.7,447C541.3,449.5 532.5,453.1 524.2,458V578ZM512,614C502.3,606.3 491.7,600.3 480.3,596C469,591.8 457.2,589.6 445,589.6C436.5,589.6 428.1,590.7 419.9,593C411.7,595.2 403.8,598.4 396.3,602.4C392,604.7 387.9,604.6 383.9,602.1C380,599.7 378,596.1 378,591.5V444.6C378,442.4 378.6,440.2 379.7,438.2C380.8,436.2 382.5,434.6 384.7,433.6C394,428.8 403.8,425.1 413.9,422.7C424.1,420.2 434.4,419 445,419C456.8,419 468.3,420.5 479.6,423.6C490.8,426.6 501.6,431.2 512,437.3C522.4,431.2 533.2,426.6 544.4,423.6C555.7,420.5 567.2,419 579,419C589.6,419 599.9,420.2 610.1,422.7C620.2,425.1 630,428.8 639.3,433.6C641.5,434.6 643.2,436.2 644.3,438.2C645.4,440.2 646,442.4 646,444.6V591.5C646,596.1 644,599.7 640.1,602.1C636.1,604.6 632,604.7 627.7,602.4C620.2,598.4 612.3,595.2 604.1,593C595.9,590.7 587.5,589.6 579,589.6C566.8,589.6 555,591.8 543.7,596C532.3,600.3 521.7,606.3 512,614Z"
|
||||
android:fillColor="#000000"/>
|
||||
</vector>
|
||||
164
app-ui-catalog/src/main/res/drawable/ic_startup_logo.xml
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="1024dp"
|
||||
android:height="1024dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M439.5,260.2L439.6,260.2C466.3,167 582.5,121.5 700.9,121.5C782.7,121.5 856.2,147.4 906.5,188.5C875.3,190.1 845.7,196.2 818.5,206C859.2,221.1 894.2,244.4 920.1,273.2C902.9,270.2 885,268.7 866.8,268.7C864.8,268.7 862.8,268.7 860.9,268.7C907.9,337 935.5,419.7 935.5,508.9C935.5,742.8 745.9,932.4 512,932.4C281.7,932.4 88.5,739.5 88.5,508.9C88.5,472.4 93.3,434.8 102.7,399.5C105.2,392.1 108.6,385 113.2,382.4C118.9,379.2 124.1,388.9 125,392C131.2,415.3 139.5,437.9 149.8,459.5C148.9,411.1 169.6,367.1 198,329C217,303.6 234.5,280 242.6,212.1C243.2,207.6 247.5,204.3 251.9,205.7C313.5,225.9 346.5,328.6 341.4,414.4C375.4,419.3 375.3,383.7 375.3,383.7C364.4,350.2 371.6,288 439.4,260.2L439.5,260.2Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="396.6"
|
||||
android:startY="288.4"
|
||||
android:endX="832.5"
|
||||
android:endY="817.9"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF88CCFC"/>
|
||||
<item android:offset="1" android:color="#FF590DF2"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M921.6,401C931.9,633.9 740.5,834.8 507,834.8C288.4,834.8 109.3,665.8 93.1,451.4C90.2,471.2 88.7,491.4 88.5,512C90.2,741.5 282.9,932.4 512,932.4C745.9,932.4 935.5,742.8 935.5,508.9C935.5,471.6 930.7,435.5 921.6,401Z"
|
||||
android:strokeAlpha="0.9"
|
||||
android:fillAlpha="0.9">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:centerX="234.4"
|
||||
android:centerY="452.7"
|
||||
android:gradientRadius="358.1"
|
||||
android:type="radial">
|
||||
<item android:offset="0.5" android:color="#000B4186"/>
|
||||
<item android:offset="1" android:color="#720B4186"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M502.2,291.3C497.6,283.2 476.5,271.3 467.3,269.2C502.2,157.6 679.7,123.3 788.4,143C833.6,151.3 889.9,175.9 907,188.7C856.7,147.6 783.2,121.7 701.4,121.7C583,121.7 466.7,167.2 440.1,260.4L440,260.4L439.9,260.4C372.1,288.2 364.9,350.5 375.8,383.9C386.2,344 436,295 502.2,291.3Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="587.8"
|
||||
android:startY="332.8"
|
||||
android:endX="442.3"
|
||||
android:endY="231"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#00D13AEF"/>
|
||||
<item android:offset="1" android:color="#E5F9D286"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M624.7,214C529.6,232.7 498.5,238.8 466.7,269.1C502.4,174.4 593.7,155.3 702.5,198.4C672.5,204.6 646.9,209.6 624.7,214Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="307.2"
|
||||
android:startY="473.7"
|
||||
android:endX="616.4"
|
||||
android:endY="164.5"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF450FB0"/>
|
||||
<item android:offset="0.8" android:color="#1E4610B1"/>
|
||||
<item android:offset="1" android:color="#00450FB0"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M111.5,386.6C85.5,493 105.6,618 223.7,723C188.5,684.6 145.6,542.6 240.3,441.2C246.7,434.4 257.6,439.4 258,448.8C265.8,659.5 435.8,788.2 631.9,764.1C571.1,760.7 370.3,690.4 519.7,662.5C597.8,648 720.3,625.2 720.3,515.3C720.3,337.1 582.5,285 499,292.8C441.8,298.1 391,334.4 375.3,383.7C381.3,403.1 357.4,416.8 341.4,414.5C346.5,328.6 313.5,225.9 251.9,205.7C247.5,204.3 243.2,207.6 242.6,212.1C234.5,280 217,303.6 198,329C169.6,367.1 148.9,411.1 149.8,459.5C139.5,437.9 131.2,415.3 125,392C124.3,389.4 120.5,382.1 115.9,381.8C113.4,381.6 112.1,384 111.5,386.6Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:centerX="352.3"
|
||||
android:centerY="739.6"
|
||||
android:gradientRadius="558.7"
|
||||
android:type="radial">
|
||||
<item android:offset="0" android:color="#FF650877"/>
|
||||
<item android:offset="1" android:color="#00340B86"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M467.2,673.3C582.2,766.7 813.5,696.7 813.5,469.6C720.1,611.2 601.2,708.8 467.2,673.3Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="778.1"
|
||||
android:startY="576.8"
|
||||
android:endX="630.1"
|
||||
android:endY="762.5"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#00D647E2"/>
|
||||
<item android:offset="1" android:color="#A3E7BB65"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M240.3,441.2C242.7,438.6 245.8,437.7 248.7,438.1C164,541.5 232.3,723.1 279.3,767.7C281.9,775.1 234.8,736.5 228.3,727.5C192.6,697.2 141.4,547.1 240.3,441.2Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="173.2"
|
||||
android:startY="429.1"
|
||||
android:endX="241.4"
|
||||
android:endY="712.5"
|
||||
android:type="linear">
|
||||
<item android:offset="0.1" android:color="#FFF9BF86"/>
|
||||
<item android:offset="1" android:color="#00D63AEF"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M512,681.9C627,681.9 720.3,605.8 720.3,511.9C720.3,418.1 627,342 512,342C413.9,342 303.7,405.8 303.7,514.4C303.8,682.2 481,778.7 632.1,764.1C620.8,762.8 550,759 502.1,704.9C497.8,700 490.3,691.5 493.7,686C497.1,680.4 506.5,681.9 512,681.9Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="512"
|
||||
android:startY="404.2"
|
||||
android:endX="512"
|
||||
android:endY="762.4"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FFFFFFFF"/>
|
||||
<item android:offset="0.9" android:color="#FFBEE1FE"/>
|
||||
<item android:offset="1" android:color="#FF96CEFD"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M541.2,257C563.5,249.9 561.6,227.9 561.6,227.9C561.6,227.9 550.4,214.8 528.3,222C507.7,228.8 504.4,243.6 504.4,243.6C504.4,243.6 515.7,265 541.2,257Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M512.5,440.5C465.2,423.4 438.7,420.8 391.5,440.5V582C438.7,567 465.3,566.7 512.5,582C564,573.1 589.7,572.9 629,582V440.5C586.8,424 560.8,426.3 512.5,440.5Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="510.3"
|
||||
android:startY="426.7"
|
||||
android:endX="510.3"
|
||||
android:endY="582"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#A3BCE0FD"/>
|
||||
<item android:offset="1" android:color="#00D647E2"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M445,561.3C454.5,561.3 463.8,562.3 472.9,564.4C481.9,566.6 490.9,569.8 499.8,574V454C491.5,449.1 482.7,445.5 473.3,443C464,440.6 454.5,439.4 445,439.4C437.7,439.4 430.4,440.1 423.2,441.5C416,442.9 409.1,445.1 402.4,447.9V568.6C409.5,566.1 416.5,564.3 423.5,563.1C430.5,561.9 437.7,561.3 445,561.3ZM524.2,574C533.1,569.8 542.1,566.6 551.1,564.4C560.2,562.3 569.5,561.3 579,561.3C586.3,561.3 593.5,561.9 600.5,563.1C607.5,564.3 614.5,566.1 621.6,568.6V447.9C614.9,445.1 608,442.9 600.8,441.5C593.6,440.1 586.3,439.4 579,439.4C569.5,439.4 560,440.6 550.7,443C541.3,445.5 532.5,449.1 524.2,454V574ZM512,610C502.3,602.3 491.7,596.3 480.3,592C469,587.8 457.2,585.6 445,585.6C436.5,585.6 428.1,586.7 419.9,589C411.7,591.2 403.8,594.4 396.3,598.4C392,600.7 387.9,600.6 383.9,598.1C380,595.7 378,592.1 378,587.5V440.6C378,438.4 378.6,436.2 379.7,434.2C380.8,432.2 382.5,430.6 384.7,429.6C394,424.8 403.8,421.1 413.9,418.7C424.1,416.2 434.4,415 445,415C456.8,415 468.3,416.5 479.6,419.6C490.8,422.6 501.6,427.2 512,433.3C522.4,427.2 533.2,422.6 544.4,419.6C555.7,416.5 567.2,415 579,415C589.6,415 599.9,416.2 610.1,418.7C620.2,421.1 630,424.8 639.3,429.6C641.5,430.6 643.2,432.2 644.3,434.2C645.4,436.2 646,438.4 646,440.6V587.5C646,592.1 644,595.7 640.1,598.1C636.1,600.6 632,600.7 627.7,598.4C620.2,594.4 612.3,591.2 604.1,589C595.9,586.7 587.5,585.6 579,585.6C566.8,585.6 555,587.8 543.7,592C532.3,596.3 521.7,602.3 512,610Z"
|
||||
android:fillColor="#0768BA"
|
||||
android:fillAlpha="0.3"/>
|
||||
<path
|
||||
android:pathData="M414.5,539.6H428.3L435.3,519.5H466.9L474.2,539.6H487.6L458.1,461H444.1L414.5,539.6ZM439.2,508.2L450.8,475.6H451.4L463,508.2H439.2ZM536.4,486.9V466.2C543.1,463.3 549.9,461.2 556.9,459.8C563.9,458.4 571.3,457.7 579,457.7C584.3,457.7 589.5,458.1 594.5,458.9C599.6,459.7 604.6,460.7 609.5,461.9V481.4C604.6,479.6 599.7,478.2 594.7,477.3C589.7,476.4 584.5,475.9 579,475.9C571.3,475.9 563.9,476.9 556.8,478.8C549.7,480.8 542.9,483.5 536.4,486.9ZM536.4,553.9V533.2C543.1,530.4 549.9,528.2 556.9,526.8C563.9,525.4 571.3,524.7 579,524.7C584.3,524.7 589.5,525.1 594.5,525.9C599.6,526.7 604.6,527.7 609.5,529V548.5C604.6,546.6 599.7,545.3 594.7,544.3C589.7,543.4 584.5,543 579,543C571.3,543 563.9,543.9 556.8,545.7C549.7,547.5 542.9,550.3 536.4,553.9ZM536.4,520.4V499.7C543.1,496.9 549.9,494.7 556.9,493.3C563.9,491.9 571.3,491.2 579,491.2C584.3,491.2 589.5,491.6 594.5,492.4C599.6,493.2 604.6,494.2 609.5,495.4V514.9C604.6,513.1 599.7,511.7 594.7,510.8C589.7,509.9 584.5,509.5 579,509.5C571.3,509.5 563.9,510.4 556.8,512.3C549.7,514.3 542.9,517 536.4,520.4ZM445,561.3C454.5,561.3 463.8,562.3 472.9,564.4C481.9,566.6 490.9,569.8 499.8,574V454C491.5,449.1 482.7,445.5 473.3,443C464,440.6 454.5,439.4 445,439.4C437.7,439.4 430.4,440.1 423.2,441.5C416,442.9 409.1,445.1 402.4,447.9V568.6C409.5,566.1 416.5,564.3 423.5,563.1C430.5,561.9 437.7,561.3 445,561.3ZM524.2,574C533.1,569.8 542.1,566.6 551.1,564.4C560.2,562.3 569.5,561.3 579,561.3C586.3,561.3 593.5,561.9 600.5,563.1C607.5,564.3 614.5,566.1 621.6,568.6V447.9C614.9,445.1 608,442.9 600.8,441.5C593.6,440.1 586.3,439.4 579,439.4C569.5,439.4 560,440.6 550.7,443C541.3,445.5 532.5,449.1 524.2,454V574ZM512,610C502.3,602.3 491.7,596.3 480.3,592C469,587.8 457.2,585.6 445,585.6C436.5,585.6 428.1,586.7 419.9,589C411.7,591.2 403.8,594.4 396.3,598.4C392,600.7 387.9,600.6 383.9,598.1C380,595.7 378,592.1 378,587.5V440.6C378,438.4 378.6,436.2 379.7,434.2C380.8,432.2 382.5,430.6 384.7,429.6C394,424.8 403.8,421.1 413.9,418.7C424.1,416.2 434.4,415 445,415C456.8,415 468.3,416.5 479.6,419.6C490.8,422.6 501.6,427.2 512,433.3C522.4,427.2 533.2,422.6 544.4,419.6C555.7,416.5 567.2,415 579,415C589.6,415 599.9,416.2 610.1,418.7C620.2,421.1 630,424.8 639.3,429.6C641.5,430.6 643.2,432.2 644.3,434.2C645.4,436.2 646,438.4 646,440.6V587.5C646,592.1 644,595.7 640.1,598.1C636.1,600.6 632,600.7 627.7,598.4C620.2,594.4 612.3,591.2 604.1,589C595.9,586.7 587.5,585.6 579,585.6C566.8,585.6 555,587.8 543.7,592C532.3,596.3 521.7,602.3 512,610Z"
|
||||
android:fillAlpha="0.9">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="472"
|
||||
android:startY="430"
|
||||
android:endX="555.5"
|
||||
android:endY="629"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF590DF2"/>
|
||||
<item android:offset="0.5" android:color="#FF1373D9"/>
|
||||
<item android:offset="1" android:color="#FFEF3ACC"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M435.3,517.5H433.8L433.4,518.8L426.8,537.6H417.4L445.5,463H456.7L484.7,537.6H475.6L468.8,518.8L468.3,517.5H466.9H435.3ZM437.3,507.6L436.4,510.2H439.2H463H465.8L464.9,507.6L453.3,475L452.8,473.6H451.4H450.8H449.4L448.9,475L437.3,507.6ZM499,575.9L501.8,577.2V574V454V452.9L500.8,452.3C492.3,447.3 483.3,443.6 473.8,441.1C464.3,438.6 454.7,437.4 445,437.4C437.6,437.4 430.2,438.1 422.8,439.5C415.5,441 408.4,443.2 401.6,446.1L400.4,446.6V447.9V568.6V571.4L403,570.5C410,568 417,566.2 423.9,565C430.8,563.8 437.8,563.3 445,563.3C454.4,563.3 463.5,564.3 472.4,566.4C481.3,568.5 490.1,571.6 499,575.9ZM522.2,574V577.2L525,575.9C533.9,571.6 542.7,568.5 551.6,566.4C560.5,564.3 569.6,563.3 579,563.3C586.2,563.3 593.2,563.8 600.1,565C607,566.2 614,568 621,570.5L623.6,571.4V568.6V447.9V446.6L622.4,446.1C615.6,443.2 608.5,441 601.2,439.5C593.8,438.1 586.4,437.4 579,437.4C569.3,437.4 559.7,438.6 550.2,441.1C540.7,443.6 531.7,447.3 523.2,452.3L522.2,452.9V454V574ZM385.5,431.4L385.6,431.4L385.6,431.4C394.8,426.6 404.4,423 414.4,420.6C424.4,418.2 434.6,417 445,417C456.6,417 467.9,418.5 479,421.5C490.1,424.5 500.8,429 511,435L512,435.6L513,435C523.2,429 533.9,424.5 545,421.5C556.1,418.5 567.4,417 579,417C589.4,417 599.6,418.2 609.6,420.6C619.6,423 629.2,426.6 638.4,431.4L638.4,431.4L638.5,431.4C640.3,432.3 641.7,433.5 642.6,435.2C643.5,436.9 644,438.7 644,440.6V587.5C644,591.4 642.4,594.3 639,596.4C635.7,598.5 632.3,598.6 628.7,596.7C621,592.5 613,589.3 604.6,587C596.3,584.8 587.7,583.6 579,583.6C566.6,583.6 554.6,585.8 543,590.2C531.9,594.3 521.6,600.1 512,607.5C502.4,600.1 492.1,594.3 481,590.2C469.4,585.8 457.4,583.6 445,583.6C436.3,583.6 427.7,584.8 419.4,587C411,589.3 403,592.5 395.3,596.7C391.7,598.6 388.3,598.5 385,596.4C381.6,594.3 380,591.4 380,587.5V440.6C380,438.7 380.5,436.9 381.4,435.2C382.3,433.5 383.7,432.3 385.5,431.4ZM607.5,463.5V478.6C603.4,477.2 599.2,476.1 595,475.3C589.9,474.4 584.6,473.9 579,473.9C571.1,473.9 563.5,474.9 556.2,476.9C550.1,478.6 544.1,480.8 538.4,483.6V467.5C544.6,465 550.9,463.1 557.3,461.7C564.2,460.4 571.4,459.7 579,459.7C584.2,459.7 589.2,460.1 594.2,460.9C598.7,461.6 603.1,462.5 607.5,463.5ZM607.5,530.5V545.6C603.4,544.2 599.2,543.1 595,542.4C589.9,541.4 584.6,541 579,541C571.1,541 563.5,541.9 556.3,543.8C550.1,545.4 544.1,547.6 538.4,550.6V534.6C544.6,532 550.9,530.1 557.3,528.8C564.2,527.4 571.4,526.7 579,526.7C584.2,526.7 589.2,527.1 594.2,527.9C598.7,528.6 603.1,529.5 607.5,530.5ZM607.5,497V512.1C603.4,510.7 599.2,509.6 595,508.9C589.9,507.9 584.6,507.5 579,507.5C571.1,507.5 563.5,508.4 556.2,510.4C550.1,512.1 544.1,514.3 538.4,517.2V501C544.6,498.5 550.9,496.6 557.3,495.3C564.2,493.9 571.4,493.2 579,493.2C584.2,493.2 589.2,493.6 594.2,494.4C598.7,495.1 603.1,496 607.5,497Z"
|
||||
android:strokeAlpha="0.2"
|
||||
android:strokeWidth="4"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#0768BA"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/launcher_icon_background" />
|
||||
<foreground>
|
||||
<inset
|
||||
android:drawable="@drawable/ic_app_logo"
|
||||
android:inset="22%"
|
||||
/>
|
||||
</foreground>
|
||||
<monochrome>
|
||||
<inset
|
||||
android:drawable="@drawable/ic_app_logo_monochrome"
|
||||
android:inset="22%"
|
||||
/>
|
||||
</monochrome>
|
||||
</adaptive-icon>
|
||||
BIN
app-ui-catalog/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
app-ui-catalog/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app-ui-catalog/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
app-ui-catalog/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
app-ui-catalog/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
4
app-ui-catalog/src/main/res/values/app_logo_colors.xml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="launcher_icon_background">#F0F8FF</color>
|
||||
</resources>
|
||||
9
app-ui-catalog/src/main/res/values/colors.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Material orange 300 -->
|
||||
<color name="ic_launcher_logo_main">#FFB74D</color>
|
||||
<!-- Material orange 700 -->
|
||||
<color name="ic_launcher_logo_shadow">#F57C00</color>
|
||||
<!-- Material orange 50 -->
|
||||
<color name="ic_launcher_background">#FFF3E0</color>
|
||||
</resources>
|
||||
3
app-ui-catalog/src/main/res/values/strings.xml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<resources>
|
||||
<string name="app_name">Thunderbird Catalog</string>
|
||||
</resources>
|
||||
13
app-ui-catalog/src/main/res/values/themes.xml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="Theme.Thunderbird" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Thunderbird.Splashscreen" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_startup_logo</item>
|
||||
<item name="windowSplashScreenAnimationDuration">1000</item>
|
||||
<item name="postSplashScreenTheme">@style/Theme.Thunderbird</item>
|
||||
</style>
|
||||
</resources>
|
||||