Compare commits
27 Commits
3b4b6b4e8e
...
71119ac4c4
| Author | SHA1 | Date | |
|---|---|---|---|
|
71119ac4c4
|
|||
|
c91eaaf1a5
|
|||
|
77802d3dc9
|
|||
|
8669a2c9ef
|
|||
|
d589df860e
|
|||
|
db25ab4e5f
|
|||
|
e855a414a4
|
|||
|
2823788765
|
|||
|
fc4baca21d
|
|||
|
e188d743f0
|
|||
|
f7dd806885
|
|||
|
326e777b7f
|
|||
|
0eb0667d2a
|
|||
|
cd97f6156f
|
|||
|
3979027471
|
|||
|
d3f3fba413
|
|||
|
7b77069744
|
|||
|
585a261bb8
|
|||
|
2631c22e52
|
|||
|
af3edb1d30
|
|||
|
ba72ef2759
|
|||
|
2639d88492
|
|||
|
04812cf56b
|
|||
|
112e30804e
|
|||
|
7e5554cfcd
|
|||
|
7e91f267e3
|
|||
|
21bb9a729f
|
4
.gitignore
vendored
@@ -17,6 +17,10 @@ build/
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Key Store
|
||||
keystore.properties
|
||||
*.jks
|
||||
|
||||
# Eclipse project files
|
||||
.classpath
|
||||
.project
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
import com.android.build.gradle.internal.api.BaseVariantOutputImpl
|
||||
import com.mikepenz.aboutlibraries.plugin.AboutLibrariesTask
|
||||
import java.io.FileInputStream
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.Properties
|
||||
|
||||
val localDateTime: LocalDateTime = LocalDateTime.now(ZoneOffset.UTC)
|
||||
val baseVersionCode = 1
|
||||
val baseVersionName = "0.0.0"
|
||||
|
||||
val keystoreProperties = rootProject.file("keystore.properties").run {
|
||||
if (!exists()) {
|
||||
null
|
||||
} else {
|
||||
Properties().apply {
|
||||
load(FileInputStream(this@run))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.androidApplication)
|
||||
@@ -17,19 +35,38 @@ plugins {
|
||||
|
||||
android {
|
||||
namespace = "top.fatweb.oxygen.toolbox"
|
||||
compileSdk = 34
|
||||
compileSdk = 35
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "top.fatweb.oxygen.toolbox"
|
||||
minSdk = 21
|
||||
targetSdk = 34
|
||||
versionCode = 1
|
||||
versionName = "1.0.0-SNAPSHOT"
|
||||
minSdk = 24
|
||||
targetSdk = 35
|
||||
versionCode = baseVersionCode
|
||||
versionName = "$baseVersionName${
|
||||
if (baseVersionCode % 100 != 0) ".${
|
||||
localDateTime.format(
|
||||
DateTimeFormatter.ofPattern("yyMMdd")
|
||||
)
|
||||
}" else ""
|
||||
}"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
useSupportLibrary = true
|
||||
}
|
||||
|
||||
setProperty("archivesBaseName", "$applicationId-v$versionName($versionCode)")
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
keystoreProperties?.let {
|
||||
create("release") {
|
||||
storeFile = rootProject.file(it["storeFile"] as String)
|
||||
storePassword = it["storePassword"] as String
|
||||
keyAlias = it["keyAlias"] as String
|
||||
keyPassword = it["keyPassword"] as String
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@@ -40,13 +77,7 @@ android {
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
android.applicationVariants.all {
|
||||
outputs.all {
|
||||
(this as BaseVariantOutputImpl).outputFileName =
|
||||
"${project.name}_${defaultConfig.versionName}-${defaultConfig.versionCode}_${buildType.name}.apk"
|
||||
signingConfig = signingConfigs.findByName("release")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,9 +95,6 @@ android {
|
||||
compose = true
|
||||
buildConfig = true
|
||||
}
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = "1.5.12"
|
||||
}
|
||||
packaging {
|
||||
resources {
|
||||
excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
||||
@@ -155,6 +183,7 @@ dependencies {
|
||||
implementation(libs.material.icons.core)
|
||||
implementation(libs.material.icons.extended)
|
||||
implementation(libs.material3.window.size)
|
||||
implementation(libs.animation.graphics)
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(libs.androidx.appcompat)
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32"
|
||||
tools:ignore="ScopedStorage" />
|
||||
|
||||
<application
|
||||
android:name=".OxygenApplication"
|
||||
|
||||
365
app/src/main/assets/template/global-variables-dark.css
Normal file
@@ -0,0 +1,365 @@
|
||||
:root {
|
||||
--blue: #1677FF;
|
||||
--blue1: #111a2c;
|
||||
--blue2: #112545;
|
||||
--blue3: #15325b;
|
||||
--blue4: #15417e;
|
||||
--blue5: #1554ad;
|
||||
--blue6: #1668dc;
|
||||
--blue7: #3c89e8;
|
||||
--blue8: #65a9f3;
|
||||
--blue9: #8dc5f8;
|
||||
--blue10: #b7dcfa;
|
||||
--purple: #722ED1;
|
||||
--purple1: #1a1325;
|
||||
--purple2: #24163a;
|
||||
--purple3: #301c4d;
|
||||
--purple4: #3e2069;
|
||||
--purple5: #51258f;
|
||||
--purple6: #642ab5;
|
||||
--purple7: #854eca;
|
||||
--purple8: #ab7ae0;
|
||||
--purple9: #cda8f0;
|
||||
--purple10: #ebd7fa;
|
||||
--cyan: #13C2C2;
|
||||
--cyan1: #112123;
|
||||
--cyan2: #113536;
|
||||
--cyan3: #144848;
|
||||
--cyan4: #146262;
|
||||
--cyan5: #138585;
|
||||
--cyan6: #13a8a8;
|
||||
--cyan7: #33bcb7;
|
||||
--cyan8: #58d1c9;
|
||||
--cyan9: #84e2d8;
|
||||
--cyan10: #b2f1e8;
|
||||
--green: #52C41A;
|
||||
--green1: #162312;
|
||||
--green2: #1d3712;
|
||||
--green3: #274916;
|
||||
--green4: #306317;
|
||||
--green5: #3c8618;
|
||||
--green6: #49aa19;
|
||||
--green7: #6abe39;
|
||||
--green8: #8fd460;
|
||||
--green9: #b2e58b;
|
||||
--green10: #d5f2bb;
|
||||
--magenta: #EB2F96;
|
||||
--magenta1: #291321;
|
||||
--magenta2: #40162f;
|
||||
--magenta3: #551c3b;
|
||||
--magenta4: #75204f;
|
||||
--magenta5: #a02669;
|
||||
--magenta6: #cb2b83;
|
||||
--magenta7: #e0529c;
|
||||
--magenta8: #f37fb7;
|
||||
--magenta9: #f8a8cc;
|
||||
--magenta10: #fad2e3;
|
||||
--pink: #EB2F96;
|
||||
--pink1: #291321;
|
||||
--pink2: #40162f;
|
||||
--pink3: #551c3b;
|
||||
--pink4: #75204f;
|
||||
--pink5: #a02669;
|
||||
--pink6: #cb2b83;
|
||||
--pink7: #e0529c;
|
||||
--pink8: #f37fb7;
|
||||
--pink9: #f8a8cc;
|
||||
--pink10: #fad2e3;
|
||||
--red: #F5222D;
|
||||
--red1: #2a1215;
|
||||
--red2: #431418;
|
||||
--red3: #58181c;
|
||||
--red4: #791a1f;
|
||||
--red5: #a61d24;
|
||||
--red6: #d32029;
|
||||
--red7: #e84749;
|
||||
--red8: #f37370;
|
||||
--red9: #f89f9a;
|
||||
--red10: #fac8c3;
|
||||
--orange: #FA8C16;
|
||||
--orange1: #2b1d11;
|
||||
--orange2: #442a11;
|
||||
--orange3: #593815;
|
||||
--orange4: #7c4a15;
|
||||
--orange5: #aa6215;
|
||||
--orange6: #d87a16;
|
||||
--orange7: #e89a3c;
|
||||
--orange8: #f3b765;
|
||||
--orange9: #f8cf8d;
|
||||
--orange10: #fae3b7;
|
||||
--yellow: #FADB14;
|
||||
--yellow1: #2b2611;
|
||||
--yellow2: #443b11;
|
||||
--yellow3: #595014;
|
||||
--yellow4: #7c6e14;
|
||||
--yellow5: #aa9514;
|
||||
--yellow6: #d8bd14;
|
||||
--yellow7: #e8d639;
|
||||
--yellow8: #f3ea62;
|
||||
--yellow9: #f8f48b;
|
||||
--yellow10: #fafab5;
|
||||
--volcano: #FA541C;
|
||||
--volcano1: #2b1611;
|
||||
--volcano2: #441d12;
|
||||
--volcano3: #592716;
|
||||
--volcano4: #7c3118;
|
||||
--volcano5: #aa3e19;
|
||||
--volcano6: #d84a1b;
|
||||
--volcano7: #e87040;
|
||||
--volcano8: #f3956a;
|
||||
--volcano9: #f8b692;
|
||||
--volcano10: #fad4bc;
|
||||
--geekblue: #2F54EB;
|
||||
--geekblue1: #131629;
|
||||
--geekblue2: #161d40;
|
||||
--geekblue3: #1c2755;
|
||||
--geekblue4: #203175;
|
||||
--geekblue5: #263ea0;
|
||||
--geekblue6: #2b4acb;
|
||||
--geekblue7: #5273e0;
|
||||
--geekblue8: #7f9ef3;
|
||||
--geekblue9: #a8c1f8;
|
||||
--geekblue10: #d2e0fa;
|
||||
--gold: #FAAD14;
|
||||
--gold1: #2b2111;
|
||||
--gold2: #443111;
|
||||
--gold3: #594214;
|
||||
--gold4: #7c5914;
|
||||
--gold5: #aa7714;
|
||||
--gold6: #d89614;
|
||||
--gold7: #e8b339;
|
||||
--gold8: #f3cc62;
|
||||
--gold9: #f8df8b;
|
||||
--gold10: #faedb5;
|
||||
--lime: #A0D911;
|
||||
--lime1: #1f2611;
|
||||
--lime2: #2e3c10;
|
||||
--lime3: #3e4f13;
|
||||
--lime4: #536d13;
|
||||
--lime5: #6f9412;
|
||||
--lime6: #8bbb11;
|
||||
--lime7: #a9d134;
|
||||
--lime8: #c9e75d;
|
||||
--lime9: #e4f88b;
|
||||
--lime10: #f0fab5;
|
||||
--colorPrimary: #453fa2;
|
||||
--colorSuccess: #49aa19;
|
||||
--colorWarning: #d89614;
|
||||
--colorError: #dc4446;
|
||||
--colorInfo: #1668dc;
|
||||
--colorLink: #1668dc;
|
||||
--colorTextBase: #fff;
|
||||
--colorBgBase: #000;
|
||||
--fontFamily: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
|
||||
'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
|
||||
'Noto Color Emoji';
|
||||
--fontFamilyCode: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
||||
--fontSize: 14;
|
||||
--lineWidth: 1;
|
||||
--lineType: solid;
|
||||
--motionUnit: 0.1;
|
||||
--motionBase: 0;
|
||||
--motionEaseOutCirc: cubic-bezier(0.08, 0.82, 0.17, 1);
|
||||
--motionEaseInOutCirc: cubic-bezier(0.78, 0.14, 0.15, 0.86);
|
||||
--motionEaseOut: cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
--motionEaseInOut: cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
--motionEaseOutBack: cubic-bezier(0.12, 0.4, 0.29, 1.46);
|
||||
--motionEaseInBack: cubic-bezier(0.71, -0.46, 0.88, 0.6);
|
||||
--motionEaseInQuint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
|
||||
--motionEaseOutQuint: cubic-bezier(0.23, 1, 0.32, 1);
|
||||
--borderRadius: 6;
|
||||
--sizeUnit: 4;
|
||||
--sizeStep: 4;
|
||||
--sizePopupArrow: 16;
|
||||
--controlHeight: 32;
|
||||
--zIndexBase: 0;
|
||||
--zIndexPopupBase: 1000;
|
||||
--opacityImage: 1;
|
||||
--colorLinkHover: #4E47BB;
|
||||
--colorText: rgba(255, 255, 255, 0.85);
|
||||
--colorTextSecondary: rgba(255, 255, 255, 0.65);
|
||||
--colorTextTertiary: rgba(255, 255, 255, 0.45);
|
||||
--colorTextQuaternary: rgba(255, 255, 255, 0.25);
|
||||
--colorFill: rgba(255, 255, 255, 0.18);
|
||||
--colorFillSecondary: rgba(255, 255, 255, 0.12);
|
||||
--colorFillTertiary: rgba(255, 255, 255, 0.08);
|
||||
--colorFillQuaternary: rgba(255, 255, 255, 0.04);
|
||||
--colorBgSolid: rgba(255, 255, 255, 0.95);
|
||||
--colorBgSolidHover: rgb(255, 255, 255);
|
||||
--colorBgSolidActive: rgba(255, 255, 255, 0.9);
|
||||
--colorBgLayout: #000000;
|
||||
--colorBgContainer: #141414;
|
||||
--colorBgElevated: #1f1f1f;
|
||||
--colorBgSpotlight: #424242;
|
||||
--colorBgBlur: rgba(255, 255, 255, 0.04);
|
||||
--colorBorder: #424242;
|
||||
--colorBorderSecondary: #303030;
|
||||
--colorPrimaryBg: #161622;
|
||||
--colorPrimaryBgHover: #1c1b34;
|
||||
--colorPrimaryBorder: #252346;
|
||||
--colorPrimaryBorderHover: #2e2b5f;
|
||||
--colorPrimaryHover: #6b62b5;
|
||||
--colorPrimaryActive: #3a3581;
|
||||
--colorPrimaryTextHover: #6b62b5;
|
||||
--colorPrimaryText: #453fa2;
|
||||
--colorPrimaryTextActive: #3a3581;
|
||||
--colorSuccessBg: #162312;
|
||||
--colorSuccessBgHover: #1d3712;
|
||||
--colorSuccessBorder: #274916;
|
||||
--colorSuccessBorderHover: #306317;
|
||||
--colorSuccessHover: #306317;
|
||||
--colorSuccessActive: #3c8618;
|
||||
--colorSuccessTextHover: #6abe39;
|
||||
--colorSuccessText: #49aa19;
|
||||
--colorSuccessTextActive: #3c8618;
|
||||
--colorErrorBg: #2c1618;
|
||||
--colorErrorBgHover: #451d1f;
|
||||
--colorErrorBgFilledHover: #441e1f;
|
||||
--colorErrorBgActive: #5b2526;
|
||||
--colorErrorBorder: #5b2526;
|
||||
--colorErrorBorderHover: #7e2e2f;
|
||||
--colorErrorHover: #e86e6b;
|
||||
--colorErrorActive: #ad393a;
|
||||
--colorErrorTextHover: #e86e6b;
|
||||
--colorErrorText: #dc4446;
|
||||
--colorErrorTextActive: #ad393a;
|
||||
--colorWarningBg: #2b2111;
|
||||
--colorWarningBgHover: #443111;
|
||||
--colorWarningBorder: #594214;
|
||||
--colorWarningBorderHover: #7c5914;
|
||||
--colorWarningHover: #7c5914;
|
||||
--colorWarningActive: #aa7714;
|
||||
--colorWarningTextHover: #e8b339;
|
||||
--colorWarningText: #d89614;
|
||||
--colorWarningTextActive: #aa7714;
|
||||
--colorInfoBg: #111a2c;
|
||||
--colorInfoBgHover: #112545;
|
||||
--colorInfoBorder: #15325b;
|
||||
--colorInfoBorderHover: #15417e;
|
||||
--colorInfoHover: #15417e;
|
||||
--colorInfoActive: #1554ad;
|
||||
--colorInfoTextHover: #3c89e8;
|
||||
--colorInfoText: #1668dc;
|
||||
--colorInfoTextActive: #1554ad;
|
||||
--colorLinkActive: #1554ad;
|
||||
--colorBgMask: rgba(0, 0, 0, 0.45);
|
||||
--colorWhite: #fff;
|
||||
--fontSizeSM: 12;
|
||||
--fontSizeLG: 16;
|
||||
--fontSizeXL: 20;
|
||||
--fontSizeHeading1: 38;
|
||||
--fontSizeHeading2: 30;
|
||||
--fontSizeHeading3: 24;
|
||||
--fontSizeHeading4: 20;
|
||||
--fontSizeHeading5: 16;
|
||||
--lineHeight: 1.5714285714285714;
|
||||
--lineHeightLG: 1.5;
|
||||
--lineHeightSM: 1.6666666666666667;
|
||||
--lineHeightHeading1: 1.2105263157894737;
|
||||
--lineHeightHeading2: 1.2666666666666666;
|
||||
--lineHeightHeading3: 1.3333333333333333;
|
||||
--lineHeightHeading4: 1.4;
|
||||
--lineHeightHeading5: 1.5;
|
||||
--sizeXXL: 48;
|
||||
--sizeXL: 32;
|
||||
--sizeLG: 24;
|
||||
--sizeMD: 20;
|
||||
--sizeMS: 16;
|
||||
--size: 16;
|
||||
--sizeSM: 12;
|
||||
--sizeXS: 8;
|
||||
--sizeXXS: 4;
|
||||
--controlHeightSM: 24;
|
||||
--controlHeightXS: 16;
|
||||
--controlHeightLG: 40;
|
||||
--motionDurationFast: 0.1s;
|
||||
--motionDurationMid: 0.2s;
|
||||
--motionDurationSlow: 0.3s;
|
||||
--lineWidthBold: 2;
|
||||
--borderRadiusXS: 2;
|
||||
--borderRadiusSM: 4;
|
||||
--borderRadiusLG: 8;
|
||||
--borderRadiusOuter: 4;
|
||||
--colorFillContent: rgba(255, 255, 255, 0.12);
|
||||
--colorFillContentHover: rgba(255, 255, 255, 0.18);
|
||||
--colorFillAlter: rgba(255, 255, 255, 0.04);
|
||||
--colorBgContainerDisabled: rgba(255, 255, 255, 0.08);
|
||||
--colorBorderBg: #141414;
|
||||
--colorSplit: rgba(253, 253, 253, 0.12);
|
||||
--colorTextPlaceholder: rgba(255, 255, 255, 0.25);
|
||||
--colorTextDisabled: rgba(255, 255, 255, 0.25);
|
||||
--colorTextHeading: rgba(255, 255, 255, 0.85);
|
||||
--colorTextLabel: rgba(255, 255, 255, 0.65);
|
||||
--colorTextDescription: rgba(255, 255, 255, 0.45);
|
||||
--colorTextLightSolid: #fff;
|
||||
--colorHighlight: #dc4446;
|
||||
--colorBgTextHover: rgba(255, 255, 255, 0.12);
|
||||
--colorBgTextActive: rgba(255, 255, 255, 0.18);
|
||||
--colorIcon: rgba(255, 255, 255, 0.45);
|
||||
--colorIconHover: rgba(255, 255, 255, 0.85);
|
||||
--colorErrorOutline: rgba(238, 38, 56, 0.11);
|
||||
--colorWarningOutline: rgba(173, 107, 0, 0.15);
|
||||
--fontSizeIcon: 12;
|
||||
--lineWidthFocus: 3;
|
||||
--controlOutlineWidth: 2;
|
||||
--controlInteractiveSize: 16;
|
||||
--controlItemBgHover: rgba(255, 255, 255, 0.08);
|
||||
--controlItemBgActive: #161622;
|
||||
--controlItemBgActiveHover: #1c1b34;
|
||||
--controlItemBgActiveDisabled: rgba(255, 255, 255, 0.18);
|
||||
--controlOutline: rgba(53, 53, 253, 0.06);
|
||||
--fontWeightStrong: 600;
|
||||
--opacityLoading: 0.65;
|
||||
--linkDecoration: none;
|
||||
--linkHoverDecoration: none;
|
||||
--linkFocusDecoration: none;
|
||||
--controlPaddingHorizontal: 12;
|
||||
--controlPaddingHorizontalSM: 8;
|
||||
--paddingXXS: 4;
|
||||
--paddingXS: 8;
|
||||
--paddingSM: 12;
|
||||
--padding: 16;
|
||||
--paddingMD: 20;
|
||||
--paddingLG: 24;
|
||||
--paddingXL: 32;
|
||||
--paddingContentHorizontalLG: 24;
|
||||
--paddingContentVerticalLG: 16;
|
||||
--paddingContentHorizontal: 16;
|
||||
--paddingContentVertical: 12;
|
||||
--paddingContentHorizontalSM: 16;
|
||||
--paddingContentVerticalSM: 8;
|
||||
--marginXXS: 4;
|
||||
--marginXS: 8;
|
||||
--marginSM: 12;
|
||||
--margin: 16;
|
||||
--marginMD: 20;
|
||||
--marginLG: 24;
|
||||
--marginXL: 32;
|
||||
--marginXXL: 48;
|
||||
--boxShadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
||||
0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
||||
0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||
--boxShadowSecondary: 0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
||||
0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
||||
0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||
--boxShadowTertiary: 0 1px 2px 0 rgba(0, 0, 0, 0.03),
|
||||
0 1px 6px -1px rgba(0, 0, 0, 0.02),
|
||||
0 2px 4px 0 rgba(0, 0, 0, 0.02);
|
||||
--screenXS: 480;
|
||||
--screenXSMin: 480;
|
||||
--screenXSMax: 575;
|
||||
--screenSM: 576;
|
||||
--screenSMMin: 576;
|
||||
--screenSMMax: 767;
|
||||
--screenMD: 768;
|
||||
--screenMDMin: 768;
|
||||
--screenMDMax: 991;
|
||||
--screenLG: 992;
|
||||
--screenLGMin: 992;
|
||||
--screenLGMax: 1199;
|
||||
--screenXL: 1200;
|
||||
--screenXLMin: 1200;
|
||||
--screenXLMax: 1599;
|
||||
--screenXXL: 1600;
|
||||
--screenXXLMin: 1600;
|
||||
}
|
||||
517
app/src/main/assets/template/global-variables-dark.js
Normal file
@@ -0,0 +1,517 @@
|
||||
const globalVariables = {
|
||||
OxygenTheme: {
|
||||
blue: '#1677FF',
|
||||
purple: '#722ED1',
|
||||
cyan: '#13C2C2',
|
||||
green: '#52C41A',
|
||||
magenta: '#EB2F96',
|
||||
pink: '#EB2F96',
|
||||
red: '#F5222D',
|
||||
orange: '#FA8C16',
|
||||
yellow: '#FADB14',
|
||||
volcano: '#FA541C',
|
||||
geekblue: '#2F54EB',
|
||||
gold: '#FAAD14',
|
||||
lime: '#A0D911',
|
||||
colorPrimary: '#453fa2',
|
||||
colorSuccess: '#49aa19',
|
||||
colorWarning: '#d89614',
|
||||
colorError: '#dc4446',
|
||||
colorInfo: '#1668dc',
|
||||
colorLink: '#1668dc',
|
||||
colorTextBase: '#fff',
|
||||
colorBgBase: '#000',
|
||||
fontFamily:
|
||||
"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,\n'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',\n'Noto Color Emoji'",
|
||||
fontFamilyCode: "'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace",
|
||||
fontSize: 14,
|
||||
lineWidth: 1,
|
||||
lineType: 'solid',
|
||||
motionUnit: 0.1,
|
||||
motionBase: 0,
|
||||
motionEaseOutCirc: 'cubic-bezier(0.08, 0.82, 0.17, 1)',
|
||||
motionEaseInOutCirc: 'cubic-bezier(0.78, 0.14, 0.15, 0.86)',
|
||||
motionEaseOut: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
|
||||
motionEaseInOut: 'cubic-bezier(0.645, 0.045, 0.355, 1)',
|
||||
motionEaseOutBack: 'cubic-bezier(0.12, 0.4, 0.29, 1.46)',
|
||||
motionEaseInBack: 'cubic-bezier(0.71, -0.46, 0.88, 0.6)',
|
||||
motionEaseInQuint: 'cubic-bezier(0.755, 0.05, 0.855, 0.06)',
|
||||
motionEaseOutQuint: 'cubic-bezier(0.23, 1, 0.32, 1)',
|
||||
borderRadius: 6,
|
||||
sizeUnit: 4,
|
||||
sizeStep: 4,
|
||||
sizePopupArrow: 16,
|
||||
controlHeight: 32,
|
||||
zIndexBase: 0,
|
||||
zIndexPopupBase: 1000,
|
||||
opacityImage: 1,
|
||||
motion: true,
|
||||
colorLinkHover: '#4E47BB',
|
||||
'blue-1': '#111a2c',
|
||||
blue1: '#111a2c',
|
||||
'blue-2': '#112545',
|
||||
blue2: '#112545',
|
||||
'blue-3': '#15325b',
|
||||
blue3: '#15325b',
|
||||
'blue-4': '#15417e',
|
||||
blue4: '#15417e',
|
||||
'blue-5': '#1554ad',
|
||||
blue5: '#1554ad',
|
||||
'blue-6': '#1668dc',
|
||||
blue6: '#1668dc',
|
||||
'blue-7': '#3c89e8',
|
||||
blue7: '#3c89e8',
|
||||
'blue-8': '#65a9f3',
|
||||
blue8: '#65a9f3',
|
||||
'blue-9': '#8dc5f8',
|
||||
blue9: '#8dc5f8',
|
||||
'blue-10': '#b7dcfa',
|
||||
blue10: '#b7dcfa',
|
||||
'purple-1': '#1a1325',
|
||||
purple1: '#1a1325',
|
||||
'purple-2': '#24163a',
|
||||
purple2: '#24163a',
|
||||
'purple-3': '#301c4d',
|
||||
purple3: '#301c4d',
|
||||
'purple-4': '#3e2069',
|
||||
purple4: '#3e2069',
|
||||
'purple-5': '#51258f',
|
||||
purple5: '#51258f',
|
||||
'purple-6': '#642ab5',
|
||||
purple6: '#642ab5',
|
||||
'purple-7': '#854eca',
|
||||
purple7: '#854eca',
|
||||
'purple-8': '#ab7ae0',
|
||||
purple8: '#ab7ae0',
|
||||
'purple-9': '#cda8f0',
|
||||
purple9: '#cda8f0',
|
||||
'purple-10': '#ebd7fa',
|
||||
purple10: '#ebd7fa',
|
||||
'cyan-1': '#112123',
|
||||
cyan1: '#112123',
|
||||
'cyan-2': '#113536',
|
||||
cyan2: '#113536',
|
||||
'cyan-3': '#144848',
|
||||
cyan3: '#144848',
|
||||
'cyan-4': '#146262',
|
||||
cyan4: '#146262',
|
||||
'cyan-5': '#138585',
|
||||
cyan5: '#138585',
|
||||
'cyan-6': '#13a8a8',
|
||||
cyan6: '#13a8a8',
|
||||
'cyan-7': '#33bcb7',
|
||||
cyan7: '#33bcb7',
|
||||
'cyan-8': '#58d1c9',
|
||||
cyan8: '#58d1c9',
|
||||
'cyan-9': '#84e2d8',
|
||||
cyan9: '#84e2d8',
|
||||
'cyan-10': '#b2f1e8',
|
||||
cyan10: '#b2f1e8',
|
||||
'green-1': '#162312',
|
||||
green1: '#162312',
|
||||
'green-2': '#1d3712',
|
||||
green2: '#1d3712',
|
||||
'green-3': '#274916',
|
||||
green3: '#274916',
|
||||
'green-4': '#306317',
|
||||
green4: '#306317',
|
||||
'green-5': '#3c8618',
|
||||
green5: '#3c8618',
|
||||
'green-6': '#49aa19',
|
||||
green6: '#49aa19',
|
||||
'green-7': '#6abe39',
|
||||
green7: '#6abe39',
|
||||
'green-8': '#8fd460',
|
||||
green8: '#8fd460',
|
||||
'green-9': '#b2e58b',
|
||||
green9: '#b2e58b',
|
||||
'green-10': '#d5f2bb',
|
||||
green10: '#d5f2bb',
|
||||
'magenta-1': '#291321',
|
||||
magenta1: '#291321',
|
||||
'magenta-2': '#40162f',
|
||||
magenta2: '#40162f',
|
||||
'magenta-3': '#551c3b',
|
||||
magenta3: '#551c3b',
|
||||
'magenta-4': '#75204f',
|
||||
magenta4: '#75204f',
|
||||
'magenta-5': '#a02669',
|
||||
magenta5: '#a02669',
|
||||
'magenta-6': '#cb2b83',
|
||||
magenta6: '#cb2b83',
|
||||
'magenta-7': '#e0529c',
|
||||
magenta7: '#e0529c',
|
||||
'magenta-8': '#f37fb7',
|
||||
magenta8: '#f37fb7',
|
||||
'magenta-9': '#f8a8cc',
|
||||
magenta9: '#f8a8cc',
|
||||
'magenta-10': '#fad2e3',
|
||||
magenta10: '#fad2e3',
|
||||
'pink-1': '#291321',
|
||||
pink1: '#291321',
|
||||
'pink-2': '#40162f',
|
||||
pink2: '#40162f',
|
||||
'pink-3': '#551c3b',
|
||||
pink3: '#551c3b',
|
||||
'pink-4': '#75204f',
|
||||
pink4: '#75204f',
|
||||
'pink-5': '#a02669',
|
||||
pink5: '#a02669',
|
||||
'pink-6': '#cb2b83',
|
||||
pink6: '#cb2b83',
|
||||
'pink-7': '#e0529c',
|
||||
pink7: '#e0529c',
|
||||
'pink-8': '#f37fb7',
|
||||
pink8: '#f37fb7',
|
||||
'pink-9': '#f8a8cc',
|
||||
pink9: '#f8a8cc',
|
||||
'pink-10': '#fad2e3',
|
||||
pink10: '#fad2e3',
|
||||
'red-1': '#2a1215',
|
||||
red1: '#2a1215',
|
||||
'red-2': '#431418',
|
||||
red2: '#431418',
|
||||
'red-3': '#58181c',
|
||||
red3: '#58181c',
|
||||
'red-4': '#791a1f',
|
||||
red4: '#791a1f',
|
||||
'red-5': '#a61d24',
|
||||
red5: '#a61d24',
|
||||
'red-6': '#d32029',
|
||||
red6: '#d32029',
|
||||
'red-7': '#e84749',
|
||||
red7: '#e84749',
|
||||
'red-8': '#f37370',
|
||||
red8: '#f37370',
|
||||
'red-9': '#f89f9a',
|
||||
red9: '#f89f9a',
|
||||
'red-10': '#fac8c3',
|
||||
red10: '#fac8c3',
|
||||
'orange-1': '#2b1d11',
|
||||
orange1: '#2b1d11',
|
||||
'orange-2': '#442a11',
|
||||
orange2: '#442a11',
|
||||
'orange-3': '#593815',
|
||||
orange3: '#593815',
|
||||
'orange-4': '#7c4a15',
|
||||
orange4: '#7c4a15',
|
||||
'orange-5': '#aa6215',
|
||||
orange5: '#aa6215',
|
||||
'orange-6': '#d87a16',
|
||||
orange6: '#d87a16',
|
||||
'orange-7': '#e89a3c',
|
||||
orange7: '#e89a3c',
|
||||
'orange-8': '#f3b765',
|
||||
orange8: '#f3b765',
|
||||
'orange-9': '#f8cf8d',
|
||||
orange9: '#f8cf8d',
|
||||
'orange-10': '#fae3b7',
|
||||
orange10: '#fae3b7',
|
||||
'yellow-1': '#2b2611',
|
||||
yellow1: '#2b2611',
|
||||
'yellow-2': '#443b11',
|
||||
yellow2: '#443b11',
|
||||
'yellow-3': '#595014',
|
||||
yellow3: '#595014',
|
||||
'yellow-4': '#7c6e14',
|
||||
yellow4: '#7c6e14',
|
||||
'yellow-5': '#aa9514',
|
||||
yellow5: '#aa9514',
|
||||
'yellow-6': '#d8bd14',
|
||||
yellow6: '#d8bd14',
|
||||
'yellow-7': '#e8d639',
|
||||
yellow7: '#e8d639',
|
||||
'yellow-8': '#f3ea62',
|
||||
yellow8: '#f3ea62',
|
||||
'yellow-9': '#f8f48b',
|
||||
yellow9: '#f8f48b',
|
||||
'yellow-10': '#fafab5',
|
||||
yellow10: '#fafab5',
|
||||
'volcano-1': '#2b1611',
|
||||
volcano1: '#2b1611',
|
||||
'volcano-2': '#441d12',
|
||||
volcano2: '#441d12',
|
||||
'volcano-3': '#592716',
|
||||
volcano3: '#592716',
|
||||
'volcano-4': '#7c3118',
|
||||
volcano4: '#7c3118',
|
||||
'volcano-5': '#aa3e19',
|
||||
volcano5: '#aa3e19',
|
||||
'volcano-6': '#d84a1b',
|
||||
volcano6: '#d84a1b',
|
||||
'volcano-7': '#e87040',
|
||||
volcano7: '#e87040',
|
||||
'volcano-8': '#f3956a',
|
||||
volcano8: '#f3956a',
|
||||
'volcano-9': '#f8b692',
|
||||
volcano9: '#f8b692',
|
||||
'volcano-10': '#fad4bc',
|
||||
volcano10: '#fad4bc',
|
||||
'geekblue-1': '#131629',
|
||||
geekblue1: '#131629',
|
||||
'geekblue-2': '#161d40',
|
||||
geekblue2: '#161d40',
|
||||
'geekblue-3': '#1c2755',
|
||||
geekblue3: '#1c2755',
|
||||
'geekblue-4': '#203175',
|
||||
geekblue4: '#203175',
|
||||
'geekblue-5': '#263ea0',
|
||||
geekblue5: '#263ea0',
|
||||
'geekblue-6': '#2b4acb',
|
||||
geekblue6: '#2b4acb',
|
||||
'geekblue-7': '#5273e0',
|
||||
geekblue7: '#5273e0',
|
||||
'geekblue-8': '#7f9ef3',
|
||||
geekblue8: '#7f9ef3',
|
||||
'geekblue-9': '#a8c1f8',
|
||||
geekblue9: '#a8c1f8',
|
||||
'geekblue-10': '#d2e0fa',
|
||||
geekblue10: '#d2e0fa',
|
||||
'gold-1': '#2b2111',
|
||||
gold1: '#2b2111',
|
||||
'gold-2': '#443111',
|
||||
gold2: '#443111',
|
||||
'gold-3': '#594214',
|
||||
gold3: '#594214',
|
||||
'gold-4': '#7c5914',
|
||||
gold4: '#7c5914',
|
||||
'gold-5': '#aa7714',
|
||||
gold5: '#aa7714',
|
||||
'gold-6': '#d89614',
|
||||
gold6: '#d89614',
|
||||
'gold-7': '#e8b339',
|
||||
gold7: '#e8b339',
|
||||
'gold-8': '#f3cc62',
|
||||
gold8: '#f3cc62',
|
||||
'gold-9': '#f8df8b',
|
||||
gold9: '#f8df8b',
|
||||
'gold-10': '#faedb5',
|
||||
gold10: '#faedb5',
|
||||
'lime-1': '#1f2611',
|
||||
lime1: '#1f2611',
|
||||
'lime-2': '#2e3c10',
|
||||
lime2: '#2e3c10',
|
||||
'lime-3': '#3e4f13',
|
||||
lime3: '#3e4f13',
|
||||
'lime-4': '#536d13',
|
||||
lime4: '#536d13',
|
||||
'lime-5': '#6f9412',
|
||||
lime5: '#6f9412',
|
||||
'lime-6': '#8bbb11',
|
||||
lime6: '#8bbb11',
|
||||
'lime-7': '#a9d134',
|
||||
lime7: '#a9d134',
|
||||
'lime-8': '#c9e75d',
|
||||
lime8: '#c9e75d',
|
||||
'lime-9': '#e4f88b',
|
||||
lime9: '#e4f88b',
|
||||
'lime-10': '#f0fab5',
|
||||
lime10: '#f0fab5',
|
||||
colorText: 'rgba(255, 255, 255, 0.85)',
|
||||
colorTextSecondary: 'rgba(255, 255, 255, 0.65)',
|
||||
colorTextTertiary: 'rgba(255, 255, 255, 0.45)',
|
||||
colorTextQuaternary: 'rgba(255, 255, 255, 0.25)',
|
||||
colorFill: 'rgba(255, 255, 255, 0.18)',
|
||||
colorFillSecondary: 'rgba(255, 255, 255, 0.12)',
|
||||
colorFillTertiary: 'rgba(255, 255, 255, 0.08)',
|
||||
colorFillQuaternary: 'rgba(255, 255, 255, 0.04)',
|
||||
colorBgSolid: 'rgba(255, 255, 255, 0.95)',
|
||||
colorBgSolidHover: 'rgb(255, 255, 255)',
|
||||
colorBgSolidActive: 'rgba(255, 255, 255, 0.9)',
|
||||
colorBgLayout: '#000000',
|
||||
colorBgContainer: '#141414',
|
||||
colorBgElevated: '#1f1f1f',
|
||||
colorBgSpotlight: '#424242',
|
||||
colorBgBlur: 'rgba(255, 255, 255, 0.04)',
|
||||
colorBorder: '#424242',
|
||||
colorBorderSecondary: '#303030',
|
||||
colorPrimaryBg: '#161622',
|
||||
colorPrimaryBgHover: '#1c1b34',
|
||||
colorPrimaryBorder: '#252346',
|
||||
colorPrimaryBorderHover: '#2e2b5f',
|
||||
colorPrimaryHover: '#6b62b5',
|
||||
colorPrimaryActive: '#3a3581',
|
||||
colorPrimaryTextHover: '#6b62b5',
|
||||
colorPrimaryText: '#453fa2',
|
||||
colorPrimaryTextActive: '#3a3581',
|
||||
colorSuccessBg: '#162312',
|
||||
colorSuccessBgHover: '#1d3712',
|
||||
colorSuccessBorder: '#274916',
|
||||
colorSuccessBorderHover: '#306317',
|
||||
colorSuccessHover: '#306317',
|
||||
colorSuccessActive: '#3c8618',
|
||||
colorSuccessTextHover: '#6abe39',
|
||||
colorSuccessText: '#49aa19',
|
||||
colorSuccessTextActive: '#3c8618',
|
||||
colorErrorBg: '#2c1618',
|
||||
colorErrorBgHover: '#451d1f',
|
||||
colorErrorBgFilledHover: '#441e1f',
|
||||
colorErrorBgActive: '#5b2526',
|
||||
colorErrorBorder: '#5b2526',
|
||||
colorErrorBorderHover: '#7e2e2f',
|
||||
colorErrorHover: '#e86e6b',
|
||||
colorErrorActive: '#ad393a',
|
||||
colorErrorTextHover: '#e86e6b',
|
||||
colorErrorText: '#dc4446',
|
||||
colorErrorTextActive: '#ad393a',
|
||||
colorWarningBg: '#2b2111',
|
||||
colorWarningBgHover: '#443111',
|
||||
colorWarningBorder: '#594214',
|
||||
colorWarningBorderHover: '#7c5914',
|
||||
colorWarningHover: '#7c5914',
|
||||
colorWarningActive: '#aa7714',
|
||||
colorWarningTextHover: '#e8b339',
|
||||
colorWarningText: '#d89614',
|
||||
colorWarningTextActive: '#aa7714',
|
||||
colorInfoBg: '#111a2c',
|
||||
colorInfoBgHover: '#112545',
|
||||
colorInfoBorder: '#15325b',
|
||||
colorInfoBorderHover: '#15417e',
|
||||
colorInfoHover: '#15417e',
|
||||
colorInfoActive: '#1554ad',
|
||||
colorInfoTextHover: '#3c89e8',
|
||||
colorInfoText: '#1668dc',
|
||||
colorInfoTextActive: '#1554ad',
|
||||
colorLinkActive: '#1554ad',
|
||||
colorBgMask: 'rgba(0, 0, 0, 0.45)',
|
||||
colorWhite: '#fff',
|
||||
fontSizeSM: 12,
|
||||
fontSizeLG: 16,
|
||||
fontSizeXL: 20,
|
||||
fontSizeHeading1: 38,
|
||||
fontSizeHeading2: 30,
|
||||
fontSizeHeading3: 24,
|
||||
fontSizeHeading4: 20,
|
||||
fontSizeHeading5: 16,
|
||||
lineHeight: 1.5714285714285714,
|
||||
lineHeightLG: 1.5,
|
||||
lineHeightSM: 1.6666666666666667,
|
||||
fontHeight: 22,
|
||||
fontHeightLG: 24,
|
||||
fontHeightSM: 20,
|
||||
lineHeightHeading1: 1.2105263157894737,
|
||||
lineHeightHeading2: 1.2666666666666666,
|
||||
lineHeightHeading3: 1.3333333333333333,
|
||||
lineHeightHeading4: 1.4,
|
||||
lineHeightHeading5: 1.5,
|
||||
sizeXXL: 48,
|
||||
sizeXL: 32,
|
||||
sizeLG: 24,
|
||||
sizeMD: 20,
|
||||
sizeMS: 16,
|
||||
size: 16,
|
||||
sizeSM: 12,
|
||||
sizeXS: 8,
|
||||
sizeXXS: 4,
|
||||
controlHeightSM: 24,
|
||||
controlHeightXS: 16,
|
||||
controlHeightLG: 40,
|
||||
motionDurationFast: '0.1s',
|
||||
motionDurationMid: '0.2s',
|
||||
motionDurationSlow: '0.3s',
|
||||
lineWidthBold: 2,
|
||||
borderRadiusXS: 2,
|
||||
borderRadiusSM: 4,
|
||||
borderRadiusLG: 8,
|
||||
borderRadiusOuter: 4,
|
||||
colorFillContent: 'rgba(255, 255, 255, 0.12)',
|
||||
colorFillContentHover: 'rgba(255, 255, 255, 0.18)',
|
||||
colorFillAlter: 'rgba(255, 255, 255, 0.04)',
|
||||
colorBgContainerDisabled: 'rgba(255, 255, 255, 0.08)',
|
||||
colorBorderBg: '#141414',
|
||||
colorSplit: 'rgba(253, 253, 253, 0.12)',
|
||||
colorTextPlaceholder: 'rgba(255, 255, 255, 0.25)',
|
||||
colorTextDisabled: 'rgba(255, 255, 255, 0.25)',
|
||||
colorTextHeading: 'rgba(255, 255, 255, 0.85)',
|
||||
colorTextLabel: 'rgba(255, 255, 255, 0.65)',
|
||||
colorTextDescription: 'rgba(255, 255, 255, 0.45)',
|
||||
colorTextLightSolid: '#fff',
|
||||
colorHighlight: '#dc4446',
|
||||
colorBgTextHover: 'rgba(255, 255, 255, 0.12)',
|
||||
colorBgTextActive: 'rgba(255, 255, 255, 0.18)',
|
||||
colorIcon: 'rgba(255, 255, 255, 0.45)',
|
||||
colorIconHover: 'rgba(255, 255, 255, 0.85)',
|
||||
colorErrorOutline: 'rgba(238, 38, 56, 0.11)',
|
||||
colorWarningOutline: 'rgba(173, 107, 0, 0.15)',
|
||||
fontSizeIcon: 12,
|
||||
lineWidthFocus: 3,
|
||||
controlOutlineWidth: 2,
|
||||
controlInteractiveSize: 16,
|
||||
controlItemBgHover: 'rgba(255, 255, 255, 0.08)',
|
||||
controlItemBgActive: '#161622',
|
||||
controlItemBgActiveHover: '#1c1b34',
|
||||
controlItemBgActiveDisabled: 'rgba(255, 255, 255, 0.18)',
|
||||
controlTmpOutline: 'rgba(255, 255, 255, 0.04)',
|
||||
controlOutline: 'rgba(53, 53, 253, 0.06)',
|
||||
fontWeightStrong: 600,
|
||||
opacityLoading: 0.65,
|
||||
linkDecoration: 'none',
|
||||
linkHoverDecoration: 'none',
|
||||
linkFocusDecoration: 'none',
|
||||
controlPaddingHorizontal: 12,
|
||||
controlPaddingHorizontalSM: 8,
|
||||
paddingXXS: 4,
|
||||
paddingXS: 8,
|
||||
paddingSM: 12,
|
||||
padding: 16,
|
||||
paddingMD: 20,
|
||||
paddingLG: 24,
|
||||
paddingXL: 32,
|
||||
paddingContentHorizontalLG: 24,
|
||||
paddingContentVerticalLG: 16,
|
||||
paddingContentHorizontal: 16,
|
||||
paddingContentVertical: 12,
|
||||
paddingContentHorizontalSM: 16,
|
||||
paddingContentVerticalSM: 8,
|
||||
marginXXS: 4,
|
||||
marginXS: 8,
|
||||
marginSM: 12,
|
||||
margin: 16,
|
||||
marginMD: 20,
|
||||
marginLG: 24,
|
||||
marginXL: 32,
|
||||
marginXXL: 48,
|
||||
boxShadow:
|
||||
'\n 0 6px 16px 0 rgba(0, 0, 0, 0.08),\n 0 3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 9px 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowSecondary:
|
||||
'\n 0 6px 16px 0 rgba(0, 0, 0, 0.08),\n 0 3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 9px 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowTertiary:
|
||||
'\n 0 1px 2px 0 rgba(0, 0, 0, 0.03),\n 0 1px 6px -1px rgba(0, 0, 0, 0.02),\n 0 2px 4px 0 rgba(0, 0, 0, 0.02)\n ',
|
||||
screenXS: 480,
|
||||
screenXSMin: 480,
|
||||
screenXSMax: 575,
|
||||
screenSM: 576,
|
||||
screenSMMin: 576,
|
||||
screenSMMax: 767,
|
||||
screenMD: 768,
|
||||
screenMDMin: 768,
|
||||
screenMDMax: 991,
|
||||
screenLG: 992,
|
||||
screenLGMin: 992,
|
||||
screenLGMax: 1199,
|
||||
screenXL: 1200,
|
||||
screenXLMin: 1200,
|
||||
screenXLMax: 1599,
|
||||
screenXXL: 1600,
|
||||
screenXXLMin: 1600,
|
||||
boxShadowPopoverArrow: '2px 2px 5px rgba(0, 0, 0, 0.05)',
|
||||
boxShadowCard:
|
||||
'\n 0 1px 2px -2px rgba(0, 0, 0, 0.16),\n 0 3px 6px 0 rgba(0, 0, 0, 0.12),\n 0 5px 12px 4px rgba(0, 0, 0, 0.09)\n ',
|
||||
boxShadowDrawerRight:
|
||||
'\n -6px 0 16px 0 rgba(0, 0, 0, 0.08),\n -3px 0 6px -4px rgba(0, 0, 0, 0.12),\n -9px 0 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowDrawerLeft:
|
||||
'\n 6px 0 16px 0 rgba(0, 0, 0, 0.08),\n 3px 0 6px -4px rgba(0, 0, 0, 0.12),\n 9px 0 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowDrawerUp:
|
||||
'\n 0 6px 16px 0 rgba(0, 0, 0, 0.08),\n 0 3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 9px 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowDrawerDown:
|
||||
'\n 0 -6px 16px 0 rgba(0, 0, 0, 0.08),\n 0 -3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 -9px 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowTabsOverflowLeft: 'inset 10px 0 8px -8px rgba(0, 0, 0, 0.08)',
|
||||
boxShadowTabsOverflowRight: 'inset -10px 0 8px -8px rgba(0, 0, 0, 0.08)',
|
||||
boxShadowTabsOverflowTop: 'inset 0 10px 8px -8px rgba(0, 0, 0, 0.08)',
|
||||
boxShadowTabsOverflowBottom: 'inset 0 -10px 8px -8px rgba(0, 0, 0, 0.08)'
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in globalVariables) {
|
||||
globalThis[key] = globalVariables[key]
|
||||
}
|
||||
365
app/src/main/assets/template/global-variables-light.css
Normal file
@@ -0,0 +1,365 @@
|
||||
:root {
|
||||
--blue: #1677FF;
|
||||
--blue1: #e6f4ff;
|
||||
--blue2: #bae0ff;
|
||||
--blue3: #91caff;
|
||||
--blue4: #69b1ff;
|
||||
--blue5: #4096ff;
|
||||
--blue6: #1677ff;
|
||||
--blue7: #0958d9;
|
||||
--blue8: #003eb3;
|
||||
--blue9: #002c8c;
|
||||
--blue10: #001d66;
|
||||
--purple: #722ED1;
|
||||
--purple1: #f9f0ff;
|
||||
--purple2: #efdbff;
|
||||
--purple3: #d3adf7;
|
||||
--purple4: #b37feb;
|
||||
--purple5: #9254de;
|
||||
--purple6: #722ed1;
|
||||
--purple7: #531dab;
|
||||
--purple8: #391085;
|
||||
--purple9: #22075e;
|
||||
--purple10: #120338;
|
||||
--cyan: #13C2C2;
|
||||
--cyan1: #e6fffb;
|
||||
--cyan2: #b5f5ec;
|
||||
--cyan3: #87e8de;
|
||||
--cyan4: #5cdbd3;
|
||||
--cyan5: #36cfc9;
|
||||
--cyan6: #13c2c2;
|
||||
--cyan7: #08979c;
|
||||
--cyan8: #006d75;
|
||||
--cyan9: #00474f;
|
||||
--cyan10: #002329;
|
||||
--green: #52C41A;
|
||||
--green1: #f6ffed;
|
||||
--green2: #d9f7be;
|
||||
--green3: #b7eb8f;
|
||||
--green4: #95de64;
|
||||
--green5: #73d13d;
|
||||
--green6: #52c41a;
|
||||
--green7: #389e0d;
|
||||
--green8: #237804;
|
||||
--green9: #135200;
|
||||
--green10: #092b00;
|
||||
--magenta: #EB2F96;
|
||||
--magenta1: #fff0f6;
|
||||
--magenta2: #ffd6e7;
|
||||
--magenta3: #ffadd2;
|
||||
--magenta4: #ff85c0;
|
||||
--magenta5: #f759ab;
|
||||
--magenta6: #eb2f96;
|
||||
--magenta7: #c41d7f;
|
||||
--magenta8: #9e1068;
|
||||
--magenta9: #780650;
|
||||
--magenta10: #520339;
|
||||
--pink: #EB2F96;
|
||||
--pink1: #fff0f6;
|
||||
--pink2: #ffd6e7;
|
||||
--pink3: #ffadd2;
|
||||
--pink4: #ff85c0;
|
||||
--pink5: #f759ab;
|
||||
--pink6: #eb2f96;
|
||||
--pink7: #c41d7f;
|
||||
--pink8: #9e1068;
|
||||
--pink9: #780650;
|
||||
--pink10: #520339;
|
||||
--red: #F5222D;
|
||||
--red1: #fff1f0;
|
||||
--red2: #ffccc7;
|
||||
--red3: #ffa39e;
|
||||
--red4: #ff7875;
|
||||
--red5: #ff4d4f;
|
||||
--red6: #f5222d;
|
||||
--red7: #cf1322;
|
||||
--red8: #a8071a;
|
||||
--red9: #820014;
|
||||
--red10: #5c0011;
|
||||
--orange: #FA8C16;
|
||||
--orange1: #fff7e6;
|
||||
--orange2: #ffe7ba;
|
||||
--orange3: #ffd591;
|
||||
--orange4: #ffc069;
|
||||
--orange5: #ffa940;
|
||||
--orange6: #fa8c16;
|
||||
--orange7: #d46b08;
|
||||
--orange8: #ad4e00;
|
||||
--orange9: #873800;
|
||||
--orange10: #612500;
|
||||
--yellow: #FADB14;
|
||||
--yellow1: #feffe6;
|
||||
--yellow2: #ffffb8;
|
||||
--yellow3: #fffb8f;
|
||||
--yellow4: #fff566;
|
||||
--yellow5: #ffec3d;
|
||||
--yellow6: #fadb14;
|
||||
--yellow7: #d4b106;
|
||||
--yellow8: #ad8b00;
|
||||
--yellow9: #876800;
|
||||
--yellow10: #614700;
|
||||
--volcano: #FA541C;
|
||||
--volcano1: #fff2e8;
|
||||
--volcano2: #ffd8bf;
|
||||
--volcano3: #ffbb96;
|
||||
--volcano4: #ff9c6e;
|
||||
--volcano5: #ff7a45;
|
||||
--volcano6: #fa541c;
|
||||
--volcano7: #d4380d;
|
||||
--volcano8: #ad2102;
|
||||
--volcano9: #871400;
|
||||
--volcano10: #610b00;
|
||||
--geekblue: #2F54EB;
|
||||
--geekblue1: #f0f5ff;
|
||||
--geekblue2: #d6e4ff;
|
||||
--geekblue3: #adc6ff;
|
||||
--geekblue4: #85a5ff;
|
||||
--geekblue5: #597ef7;
|
||||
--geekblue6: #2f54eb;
|
||||
--geekblue7: #1d39c4;
|
||||
--geekblue8: #10239e;
|
||||
--geekblue9: #061178;
|
||||
--geekblue10: #030852;
|
||||
--gold: #FAAD14;
|
||||
--gold1: #fffbe6;
|
||||
--gold2: #fff1b8;
|
||||
--gold3: #ffe58f;
|
||||
--gold4: #ffd666;
|
||||
--gold5: #ffc53d;
|
||||
--gold6: #faad14;
|
||||
--gold7: #d48806;
|
||||
--gold8: #ad6800;
|
||||
--gold9: #874d00;
|
||||
--gold10: #613400;
|
||||
--lime: #A0D911;
|
||||
--lime1: #fcffe6;
|
||||
--lime2: #f4ffb8;
|
||||
--lime3: #eaff8f;
|
||||
--lime4: #d3f261;
|
||||
--lime5: #bae637;
|
||||
--lime6: #a0d911;
|
||||
--lime7: #7cb305;
|
||||
--lime8: #5b8c00;
|
||||
--lime9: #3f6600;
|
||||
--lime10: #254000;
|
||||
--colorPrimary: #4e47bb;
|
||||
--colorSuccess: #52c41a;
|
||||
--colorWarning: #faad14;
|
||||
--colorError: #ff4d4f;
|
||||
--colorInfo: #1677ff;
|
||||
--colorLink: #1677ff;
|
||||
--colorTextBase: #000;
|
||||
--colorBgBase: #fff;
|
||||
--fontFamily: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
|
||||
'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
|
||||
'Noto Color Emoji';
|
||||
--fontFamilyCode: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
||||
--fontSize: 14;
|
||||
--lineWidth: 1;
|
||||
--lineType: solid;
|
||||
--motionUnit: 0.1;
|
||||
--motionBase: 0;
|
||||
--motionEaseOutCirc: cubic-bezier(0.08, 0.82, 0.17, 1);
|
||||
--motionEaseInOutCirc: cubic-bezier(0.78, 0.14, 0.15, 0.86);
|
||||
--motionEaseOut: cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
--motionEaseInOut: cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
--motionEaseOutBack: cubic-bezier(0.12, 0.4, 0.29, 1.46);
|
||||
--motionEaseInBack: cubic-bezier(0.71, -0.46, 0.88, 0.6);
|
||||
--motionEaseInQuint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
|
||||
--motionEaseOutQuint: cubic-bezier(0.23, 1, 0.32, 1);
|
||||
--borderRadius: 6;
|
||||
--sizeUnit: 4;
|
||||
--sizeStep: 4;
|
||||
--sizePopupArrow: 16;
|
||||
--controlHeight: 32;
|
||||
--zIndexBase: 0;
|
||||
--zIndexPopupBase: 1000;
|
||||
--opacityImage: 1;
|
||||
--colorLinkHover: #4E47BB;
|
||||
--colorText: rgba(0, 0, 0, 0.88);
|
||||
--colorTextSecondary: rgba(0, 0, 0, 0.65);
|
||||
--colorTextTertiary: rgba(0, 0, 0, 0.45);
|
||||
--colorTextQuaternary: rgba(0, 0, 0, 0.25);
|
||||
--colorFill: rgba(0, 0, 0, 0.15);
|
||||
--colorFillSecondary: rgba(0, 0, 0, 0.06);
|
||||
--colorFillTertiary: rgba(0, 0, 0, 0.04);
|
||||
--colorFillQuaternary: rgba(0, 0, 0, 0.02);
|
||||
--colorBgSolid: rgb(0, 0, 0);
|
||||
--colorBgSolidHover: rgba(0, 0, 0, 0.75);
|
||||
--colorBgSolidActive: rgba(0, 0, 0, 0.95);
|
||||
--colorBgLayout: #f5f5f5;
|
||||
--colorBgContainer: #ffffff;
|
||||
--colorBgElevated: #ffffff;
|
||||
--colorBgSpotlight: rgba(0, 0, 0, 0.85);
|
||||
--colorBgBlur: transparent;
|
||||
--colorBorder: #d9d9d9;
|
||||
--colorBorderSecondary: #f0f0f0;
|
||||
--colorPrimaryBg: #eeebfa;
|
||||
--colorPrimaryBgHover: #e2dfed;
|
||||
--colorPrimaryBorder: #c6c1e0;
|
||||
--colorPrimaryBorderHover: #9d94d4;
|
||||
--colorPrimaryHover: #756bc7;
|
||||
--colorPrimaryActive: #343194;
|
||||
--colorPrimaryTextHover: #756bc7;
|
||||
--colorPrimaryText: #4e47bb;
|
||||
--colorPrimaryTextActive: #343194;
|
||||
--colorSuccessBg: #f6ffed;
|
||||
--colorSuccessBgHover: #d9f7be;
|
||||
--colorSuccessBorder: #b7eb8f;
|
||||
--colorSuccessBorderHover: #95de64;
|
||||
--colorSuccessHover: #95de64;
|
||||
--colorSuccessActive: #389e0d;
|
||||
--colorSuccessTextHover: #73d13d;
|
||||
--colorSuccessText: #52c41a;
|
||||
--colorSuccessTextActive: #389e0d;
|
||||
--colorErrorBg: #fff2f0;
|
||||
--colorErrorBgHover: #fff1f0;
|
||||
--colorErrorBgFilledHover: #ffdfdc;
|
||||
--colorErrorBgActive: #ffccc7;
|
||||
--colorErrorBorder: #ffccc7;
|
||||
--colorErrorBorderHover: #ffa39e;
|
||||
--colorErrorHover: #ff7875;
|
||||
--colorErrorActive: #d9363e;
|
||||
--colorErrorTextHover: #ff7875;
|
||||
--colorErrorText: #ff4d4f;
|
||||
--colorErrorTextActive: #d9363e;
|
||||
--colorWarningBg: #fffbe6;
|
||||
--colorWarningBgHover: #fff1b8;
|
||||
--colorWarningBorder: #ffe58f;
|
||||
--colorWarningBorderHover: #ffd666;
|
||||
--colorWarningHover: #ffd666;
|
||||
--colorWarningActive: #d48806;
|
||||
--colorWarningTextHover: #ffc53d;
|
||||
--colorWarningText: #faad14;
|
||||
--colorWarningTextActive: #d48806;
|
||||
--colorInfoBg: #e6f4ff;
|
||||
--colorInfoBgHover: #bae0ff;
|
||||
--colorInfoBorder: #91caff;
|
||||
--colorInfoBorderHover: #69b1ff;
|
||||
--colorInfoHover: #69b1ff;
|
||||
--colorInfoActive: #0958d9;
|
||||
--colorInfoTextHover: #4096ff;
|
||||
--colorInfoText: #1677ff;
|
||||
--colorInfoTextActive: #0958d9;
|
||||
--colorLinkActive: #0958d9;
|
||||
--colorBgMask: rgba(0, 0, 0, 0.45);
|
||||
--colorWhite: #fff;
|
||||
--fontSizeSM: 12;
|
||||
--fontSizeLG: 16;
|
||||
--fontSizeXL: 20;
|
||||
--fontSizeHeading1: 38;
|
||||
--fontSizeHeading2: 30;
|
||||
--fontSizeHeading3: 24;
|
||||
--fontSizeHeading4: 20;
|
||||
--fontSizeHeading5: 16;
|
||||
--lineHeight: 1.5714285714285714;
|
||||
--lineHeightLG: 1.5;
|
||||
--lineHeightSM: 1.6666666666666667;
|
||||
--lineHeightHeading1: 1.2105263157894737;
|
||||
--lineHeightHeading2: 1.2666666666666666;
|
||||
--lineHeightHeading3: 1.3333333333333333;
|
||||
--lineHeightHeading4: 1.4;
|
||||
--lineHeightHeading5: 1.5;
|
||||
--sizeXXL: 48;
|
||||
--sizeXL: 32;
|
||||
--sizeLG: 24;
|
||||
--sizeMD: 20;
|
||||
--sizeMS: 16;
|
||||
--size: 16;
|
||||
--sizeSM: 12;
|
||||
--sizeXS: 8;
|
||||
--sizeXXS: 4;
|
||||
--controlHeightSM: 24;
|
||||
--controlHeightXS: 16;
|
||||
--controlHeightLG: 40;
|
||||
--motionDurationFast: 0.1s;
|
||||
--motionDurationMid: 0.2s;
|
||||
--motionDurationSlow: 0.3s;
|
||||
--lineWidthBold: 2;
|
||||
--borderRadiusXS: 2;
|
||||
--borderRadiusSM: 4;
|
||||
--borderRadiusLG: 8;
|
||||
--borderRadiusOuter: 4;
|
||||
--colorFillContent: rgba(0, 0, 0, 0.06);
|
||||
--colorFillContentHover: rgba(0, 0, 0, 0.15);
|
||||
--colorFillAlter: rgba(0, 0, 0, 0.02);
|
||||
--colorBgContainerDisabled: rgba(0, 0, 0, 0.04);
|
||||
--colorBorderBg: #ffffff;
|
||||
--colorSplit: rgba(5, 5, 5, 0.06);
|
||||
--colorTextPlaceholder: rgba(0, 0, 0, 0.25);
|
||||
--colorTextDisabled: rgba(0, 0, 0, 0.25);
|
||||
--colorTextHeading: rgba(0, 0, 0, 0.88);
|
||||
--colorTextLabel: rgba(0, 0, 0, 0.65);
|
||||
--colorTextDescription: rgba(0, 0, 0, 0.45);
|
||||
--colorTextLightSolid: #fff;
|
||||
--colorHighlight: #ff4d4f;
|
||||
--colorBgTextHover: rgba(0, 0, 0, 0.06);
|
||||
--colorBgTextActive: rgba(0, 0, 0, 0.15);
|
||||
--colorIcon: rgba(0, 0, 0, 0.45);
|
||||
--colorIconHover: rgba(0, 0, 0, 0.88);
|
||||
--colorErrorOutline: rgba(255, 38, 5, 0.06);
|
||||
--colorWarningOutline: rgba(255, 215, 5, 0.1);
|
||||
--fontSizeIcon: 12;
|
||||
--lineWidthFocus: 3;
|
||||
--controlOutlineWidth: 2;
|
||||
--controlInteractiveSize: 16;
|
||||
--controlItemBgHover: rgba(0, 0, 0, 0.04);
|
||||
--controlItemBgActive: #eeebfa;
|
||||
--controlItemBgActiveHover: #e2dfed;
|
||||
--controlItemBgActiveDisabled: rgba(0, 0, 0, 0.15);
|
||||
--controlOutline: rgba(42, 5, 192, 0.08);
|
||||
--fontWeightStrong: 600;
|
||||
--opacityLoading: 0.65;
|
||||
--linkDecoration: none;
|
||||
--linkHoverDecoration: none;
|
||||
--linkFocusDecoration: none;
|
||||
--controlPaddingHorizontal: 12;
|
||||
--controlPaddingHorizontalSM: 8;
|
||||
--paddingXXS: 4;
|
||||
--paddingXS: 8;
|
||||
--paddingSM: 12;
|
||||
--padding: 16;
|
||||
--paddingMD: 20;
|
||||
--paddingLG: 24;
|
||||
--paddingXL: 32;
|
||||
--paddingContentHorizontalLG: 24;
|
||||
--paddingContentVerticalLG: 16;
|
||||
--paddingContentHorizontal: 16;
|
||||
--paddingContentVertical: 12;
|
||||
--paddingContentHorizontalSM: 16;
|
||||
--paddingContentVerticalSM: 8;
|
||||
--marginXXS: 4;
|
||||
--marginXS: 8;
|
||||
--marginSM: 12;
|
||||
--margin: 16;
|
||||
--marginMD: 20;
|
||||
--marginLG: 24;
|
||||
--marginXL: 32;
|
||||
--marginXXL: 48;
|
||||
--boxShadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
||||
0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
||||
0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||
--boxShadowSecondary: 0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
||||
0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
||||
0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||
--boxShadowTertiary: 0 1px 2px 0 rgba(0, 0, 0, 0.03),
|
||||
0 1px 6px -1px rgba(0, 0, 0, 0.02),
|
||||
0 2px 4px 0 rgba(0, 0, 0, 0.02);
|
||||
--screenXS: 480;
|
||||
--screenXSMin: 480;
|
||||
--screenXSMax: 575;
|
||||
--screenSM: 576;
|
||||
--screenSMMin: 576;
|
||||
--screenSMMax: 767;
|
||||
--screenMD: 768;
|
||||
--screenMDMin: 768;
|
||||
--screenMDMax: 991;
|
||||
--screenLG: 992;
|
||||
--screenLGMin: 992;
|
||||
--screenLGMax: 1199;
|
||||
--screenXL: 1200;
|
||||
--screenXLMin: 1200;
|
||||
--screenXLMax: 1599;
|
||||
--screenXXL: 1600;
|
||||
--screenXXLMin: 1600;
|
||||
}
|
||||
518
app/src/main/assets/template/global-variables-light.js
Normal file
@@ -0,0 +1,518 @@
|
||||
const globalVariables = {
|
||||
OxygenTheme: {
|
||||
blue: '#1677FF',
|
||||
purple: '#722ED1',
|
||||
cyan: '#13C2C2',
|
||||
green: '#52C41A',
|
||||
magenta: '#EB2F96',
|
||||
pink: '#EB2F96',
|
||||
red: '#F5222D',
|
||||
orange: '#FA8C16',
|
||||
yellow: '#FADB14',
|
||||
volcano: '#FA541C',
|
||||
geekblue: '#2F54EB',
|
||||
gold: '#FAAD14',
|
||||
lime: '#A0D911',
|
||||
colorPrimary: '#4e47bb',
|
||||
colorSuccess: '#52c41a',
|
||||
colorWarning: '#faad14',
|
||||
colorError: '#ff4d4f',
|
||||
colorInfo: '#1677ff',
|
||||
colorLink: '#1677ff',
|
||||
colorTextBase: '#000',
|
||||
colorBgBase: '#fff',
|
||||
fontFamily:
|
||||
"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,\n'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',\n'Noto Color Emoji'",
|
||||
fontFamilyCode: "'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace",
|
||||
fontSize: 14,
|
||||
lineWidth: 1,
|
||||
lineType: 'solid',
|
||||
motionUnit: 0.1,
|
||||
motionBase: 0,
|
||||
motionEaseOutCirc: 'cubic-bezier(0.08, 0.82, 0.17, 1)',
|
||||
motionEaseInOutCirc: 'cubic-bezier(0.78, 0.14, 0.15, 0.86)',
|
||||
motionEaseOut: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
|
||||
motionEaseInOut: 'cubic-bezier(0.645, 0.045, 0.355, 1)',
|
||||
motionEaseOutBack: 'cubic-bezier(0.12, 0.4, 0.29, 1.46)',
|
||||
motionEaseInBack: 'cubic-bezier(0.71, -0.46, 0.88, 0.6)',
|
||||
motionEaseInQuint: 'cubic-bezier(0.755, 0.05, 0.855, 0.06)',
|
||||
motionEaseOutQuint: 'cubic-bezier(0.23, 1, 0.32, 1)',
|
||||
borderRadius: 6,
|
||||
sizeUnit: 4,
|
||||
sizeStep: 4,
|
||||
sizePopupArrow: 16,
|
||||
controlHeight: 32,
|
||||
zIndexBase: 0,
|
||||
zIndexPopupBase: 1000,
|
||||
opacityImage: 1,
|
||||
motion: true,
|
||||
colorLinkHover: '#4E47BB',
|
||||
'blue-1': '#e6f4ff',
|
||||
blue1: '#e6f4ff',
|
||||
'blue-2': '#bae0ff',
|
||||
blue2: '#bae0ff',
|
||||
'blue-3': '#91caff',
|
||||
blue3: '#91caff',
|
||||
'blue-4': '#69b1ff',
|
||||
blue4: '#69b1ff',
|
||||
'blue-5': '#4096ff',
|
||||
blue5: '#4096ff',
|
||||
'blue-6': '#1677ff',
|
||||
blue6: '#1677ff',
|
||||
'blue-7': '#0958d9',
|
||||
blue7: '#0958d9',
|
||||
'blue-8': '#003eb3',
|
||||
blue8: '#003eb3',
|
||||
'blue-9': '#002c8c',
|
||||
blue9: '#002c8c',
|
||||
'blue-10': '#001d66',
|
||||
blue10: '#001d66',
|
||||
'purple-1': '#f9f0ff',
|
||||
purple1: '#f9f0ff',
|
||||
'purple-2': '#efdbff',
|
||||
purple2: '#efdbff',
|
||||
'purple-3': '#d3adf7',
|
||||
purple3: '#d3adf7',
|
||||
'purple-4': '#b37feb',
|
||||
purple4: '#b37feb',
|
||||
'purple-5': '#9254de',
|
||||
purple5: '#9254de',
|
||||
'purple-6': '#722ed1',
|
||||
purple6: '#722ed1',
|
||||
'purple-7': '#531dab',
|
||||
purple7: '#531dab',
|
||||
'purple-8': '#391085',
|
||||
purple8: '#391085',
|
||||
'purple-9': '#22075e',
|
||||
purple9: '#22075e',
|
||||
'purple-10': '#120338',
|
||||
purple10: '#120338',
|
||||
'cyan-1': '#e6fffb',
|
||||
cyan1: '#e6fffb',
|
||||
'cyan-2': '#b5f5ec',
|
||||
cyan2: '#b5f5ec',
|
||||
'cyan-3': '#87e8de',
|
||||
cyan3: '#87e8de',
|
||||
'cyan-4': '#5cdbd3',
|
||||
cyan4: '#5cdbd3',
|
||||
'cyan-5': '#36cfc9',
|
||||
cyan5: '#36cfc9',
|
||||
'cyan-6': '#13c2c2',
|
||||
cyan6: '#13c2c2',
|
||||
'cyan-7': '#08979c',
|
||||
cyan7: '#08979c',
|
||||
'cyan-8': '#006d75',
|
||||
cyan8: '#006d75',
|
||||
'cyan-9': '#00474f',
|
||||
cyan9: '#00474f',
|
||||
'cyan-10': '#002329',
|
||||
cyan10: '#002329',
|
||||
'green-1': '#f6ffed',
|
||||
green1: '#f6ffed',
|
||||
'green-2': '#d9f7be',
|
||||
green2: '#d9f7be',
|
||||
'green-3': '#b7eb8f',
|
||||
green3: '#b7eb8f',
|
||||
'green-4': '#95de64',
|
||||
green4: '#95de64',
|
||||
'green-5': '#73d13d',
|
||||
green5: '#73d13d',
|
||||
'green-6': '#52c41a',
|
||||
green6: '#52c41a',
|
||||
'green-7': '#389e0d',
|
||||
green7: '#389e0d',
|
||||
'green-8': '#237804',
|
||||
green8: '#237804',
|
||||
'green-9': '#135200',
|
||||
green9: '#135200',
|
||||
'green-10': '#092b00',
|
||||
green10: '#092b00',
|
||||
'magenta-1': '#fff0f6',
|
||||
magenta1: '#fff0f6',
|
||||
'magenta-2': '#ffd6e7',
|
||||
magenta2: '#ffd6e7',
|
||||
'magenta-3': '#ffadd2',
|
||||
magenta3: '#ffadd2',
|
||||
'magenta-4': '#ff85c0',
|
||||
magenta4: '#ff85c0',
|
||||
'magenta-5': '#f759ab',
|
||||
magenta5: '#f759ab',
|
||||
'magenta-6': '#eb2f96',
|
||||
magenta6: '#eb2f96',
|
||||
'magenta-7': '#c41d7f',
|
||||
magenta7: '#c41d7f',
|
||||
'magenta-8': '#9e1068',
|
||||
magenta8: '#9e1068',
|
||||
'magenta-9': '#780650',
|
||||
magenta9: '#780650',
|
||||
'magenta-10': '#520339',
|
||||
magenta10: '#520339',
|
||||
'pink-1': '#fff0f6',
|
||||
pink1: '#fff0f6',
|
||||
'pink-2': '#ffd6e7',
|
||||
pink2: '#ffd6e7',
|
||||
'pink-3': '#ffadd2',
|
||||
pink3: '#ffadd2',
|
||||
'pink-4': '#ff85c0',
|
||||
pink4: '#ff85c0',
|
||||
'pink-5': '#f759ab',
|
||||
pink5: '#f759ab',
|
||||
'pink-6': '#eb2f96',
|
||||
pink6: '#eb2f96',
|
||||
'pink-7': '#c41d7f',
|
||||
pink7: '#c41d7f',
|
||||
'pink-8': '#9e1068',
|
||||
pink8: '#9e1068',
|
||||
'pink-9': '#780650',
|
||||
pink9: '#780650',
|
||||
'pink-10': '#520339',
|
||||
pink10: '#520339',
|
||||
'red-1': '#fff1f0',
|
||||
red1: '#fff1f0',
|
||||
'red-2': '#ffccc7',
|
||||
red2: '#ffccc7',
|
||||
'red-3': '#ffa39e',
|
||||
red3: '#ffa39e',
|
||||
'red-4': '#ff7875',
|
||||
red4: '#ff7875',
|
||||
'red-5': '#ff4d4f',
|
||||
red5: '#ff4d4f',
|
||||
'red-6': '#f5222d',
|
||||
red6: '#f5222d',
|
||||
'red-7': '#cf1322',
|
||||
red7: '#cf1322',
|
||||
'red-8': '#a8071a',
|
||||
red8: '#a8071a',
|
||||
'red-9': '#820014',
|
||||
red9: '#820014',
|
||||
'red-10': '#5c0011',
|
||||
red10: '#5c0011',
|
||||
'orange-1': '#fff7e6',
|
||||
orange1: '#fff7e6',
|
||||
'orange-2': '#ffe7ba',
|
||||
orange2: '#ffe7ba',
|
||||
'orange-3': '#ffd591',
|
||||
orange3: '#ffd591',
|
||||
'orange-4': '#ffc069',
|
||||
orange4: '#ffc069',
|
||||
'orange-5': '#ffa940',
|
||||
orange5: '#ffa940',
|
||||
'orange-6': '#fa8c16',
|
||||
orange6: '#fa8c16',
|
||||
'orange-7': '#d46b08',
|
||||
orange7: '#d46b08',
|
||||
'orange-8': '#ad4e00',
|
||||
orange8: '#ad4e00',
|
||||
'orange-9': '#873800',
|
||||
orange9: '#873800',
|
||||
'orange-10': '#612500',
|
||||
orange10: '#612500',
|
||||
'yellow-1': '#feffe6',
|
||||
yellow1: '#feffe6',
|
||||
'yellow-2': '#ffffb8',
|
||||
yellow2: '#ffffb8',
|
||||
'yellow-3': '#fffb8f',
|
||||
yellow3: '#fffb8f',
|
||||
'yellow-4': '#fff566',
|
||||
yellow4: '#fff566',
|
||||
'yellow-5': '#ffec3d',
|
||||
yellow5: '#ffec3d',
|
||||
'yellow-6': '#fadb14',
|
||||
yellow6: '#fadb14',
|
||||
'yellow-7': '#d4b106',
|
||||
yellow7: '#d4b106',
|
||||
'yellow-8': '#ad8b00',
|
||||
yellow8: '#ad8b00',
|
||||
'yellow-9': '#876800',
|
||||
yellow9: '#876800',
|
||||
'yellow-10': '#614700',
|
||||
yellow10: '#614700',
|
||||
'volcano-1': '#fff2e8',
|
||||
volcano1: '#fff2e8',
|
||||
'volcano-2': '#ffd8bf',
|
||||
volcano2: '#ffd8bf',
|
||||
'volcano-3': '#ffbb96',
|
||||
volcano3: '#ffbb96',
|
||||
'volcano-4': '#ff9c6e',
|
||||
volcano4: '#ff9c6e',
|
||||
'volcano-5': '#ff7a45',
|
||||
volcano5: '#ff7a45',
|
||||
'volcano-6': '#fa541c',
|
||||
volcano6: '#fa541c',
|
||||
'volcano-7': '#d4380d',
|
||||
volcano7: '#d4380d',
|
||||
'volcano-8': '#ad2102',
|
||||
volcano8: '#ad2102',
|
||||
'volcano-9': '#871400',
|
||||
volcano9: '#871400',
|
||||
'volcano-10': '#610b00',
|
||||
volcano10: '#610b00',
|
||||
'geekblue-1': '#f0f5ff',
|
||||
geekblue1: '#f0f5ff',
|
||||
'geekblue-2': '#d6e4ff',
|
||||
geekblue2: '#d6e4ff',
|
||||
'geekblue-3': '#adc6ff',
|
||||
geekblue3: '#adc6ff',
|
||||
'geekblue-4': '#85a5ff',
|
||||
geekblue4: '#85a5ff',
|
||||
'geekblue-5': '#597ef7',
|
||||
geekblue5: '#597ef7',
|
||||
'geekblue-6': '#2f54eb',
|
||||
geekblue6: '#2f54eb',
|
||||
'geekblue-7': '#1d39c4',
|
||||
geekblue7: '#1d39c4',
|
||||
'geekblue-8': '#10239e',
|
||||
geekblue8: '#10239e',
|
||||
'geekblue-9': '#061178',
|
||||
geekblue9: '#061178',
|
||||
'geekblue-10': '#030852',
|
||||
geekblue10: '#030852',
|
||||
'gold-1': '#fffbe6',
|
||||
gold1: '#fffbe6',
|
||||
'gold-2': '#fff1b8',
|
||||
gold2: '#fff1b8',
|
||||
'gold-3': '#ffe58f',
|
||||
gold3: '#ffe58f',
|
||||
'gold-4': '#ffd666',
|
||||
gold4: '#ffd666',
|
||||
'gold-5': '#ffc53d',
|
||||
gold5: '#ffc53d',
|
||||
'gold-6': '#faad14',
|
||||
gold6: '#faad14',
|
||||
'gold-7': '#d48806',
|
||||
gold7: '#d48806',
|
||||
'gold-8': '#ad6800',
|
||||
gold8: '#ad6800',
|
||||
'gold-9': '#874d00',
|
||||
gold9: '#874d00',
|
||||
'gold-10': '#613400',
|
||||
gold10: '#613400',
|
||||
'lime-1': '#fcffe6',
|
||||
lime1: '#fcffe6',
|
||||
'lime-2': '#f4ffb8',
|
||||
lime2: '#f4ffb8',
|
||||
'lime-3': '#eaff8f',
|
||||
lime3: '#eaff8f',
|
||||
'lime-4': '#d3f261',
|
||||
lime4: '#d3f261',
|
||||
'lime-5': '#bae637',
|
||||
lime5: '#bae637',
|
||||
'lime-6': '#a0d911',
|
||||
lime6: '#a0d911',
|
||||
'lime-7': '#7cb305',
|
||||
lime7: '#7cb305',
|
||||
'lime-8': '#5b8c00',
|
||||
lime8: '#5b8c00',
|
||||
'lime-9': '#3f6600',
|
||||
lime9: '#3f6600',
|
||||
'lime-10': '#254000',
|
||||
lime10: '#254000',
|
||||
colorText: 'rgba(0, 0, 0, 0.88)',
|
||||
colorTextSecondary: 'rgba(0, 0, 0, 0.65)',
|
||||
colorTextTertiary: 'rgba(0, 0, 0, 0.45)',
|
||||
colorTextQuaternary: 'rgba(0, 0, 0, 0.25)',
|
||||
colorFill: 'rgba(0, 0, 0, 0.15)',
|
||||
colorFillSecondary: 'rgba(0, 0, 0, 0.06)',
|
||||
colorFillTertiary: 'rgba(0, 0, 0, 0.04)',
|
||||
colorFillQuaternary: 'rgba(0, 0, 0, 0.02)',
|
||||
colorBgSolid: 'rgb(0, 0, 0)',
|
||||
colorBgSolidHover: 'rgba(0, 0, 0, 0.75)',
|
||||
colorBgSolidActive: 'rgba(0, 0, 0, 0.95)',
|
||||
colorBgLayout: '#f5f5f5',
|
||||
colorBgContainer: '#ffffff',
|
||||
colorBgElevated: '#ffffff',
|
||||
colorBgSpotlight: 'rgba(0, 0, 0, 0.85)',
|
||||
colorBgBlur: 'transparent',
|
||||
colorBorder: '#d9d9d9',
|
||||
colorBorderSecondary: '#f0f0f0',
|
||||
colorPrimaryBg: '#eeebfa',
|
||||
colorPrimaryBgHover: '#e2dfed',
|
||||
colorPrimaryBorder: '#c6c1e0',
|
||||
colorPrimaryBorderHover: '#9d94d4',
|
||||
colorPrimaryHover: '#756bc7',
|
||||
colorPrimaryActive: '#343194',
|
||||
colorPrimaryTextHover: '#756bc7',
|
||||
colorPrimaryText: '#4e47bb',
|
||||
colorPrimaryTextActive: '#343194',
|
||||
colorSuccessBg: '#f6ffed',
|
||||
colorSuccessBgHover: '#d9f7be',
|
||||
colorSuccessBorder: '#b7eb8f',
|
||||
colorSuccessBorderHover: '#95de64',
|
||||
colorSuccessHover: '#95de64',
|
||||
colorSuccessActive: '#389e0d',
|
||||
colorSuccessTextHover: '#73d13d',
|
||||
colorSuccessText: '#52c41a',
|
||||
colorSuccessTextActive: '#389e0d',
|
||||
colorErrorBg: '#fff2f0',
|
||||
colorErrorBgHover: '#fff1f0',
|
||||
colorErrorBgFilledHover: '#ffdfdc',
|
||||
colorErrorBgActive: '#ffccc7',
|
||||
colorErrorBorder: '#ffccc7',
|
||||
colorErrorBorderHover: '#ffa39e',
|
||||
colorErrorHover: '#ff7875',
|
||||
colorErrorActive: '#d9363e',
|
||||
colorErrorTextHover: '#ff7875',
|
||||
colorErrorText: '#ff4d4f',
|
||||
colorErrorTextActive: '#d9363e',
|
||||
colorWarningBg: '#fffbe6',
|
||||
colorWarningBgHover: '#fff1b8',
|
||||
colorWarningBorder: '#ffe58f',
|
||||
colorWarningBorderHover: '#ffd666',
|
||||
colorWarningHover: '#ffd666',
|
||||
colorWarningActive: '#d48806',
|
||||
colorWarningTextHover: '#ffc53d',
|
||||
colorWarningText: '#faad14',
|
||||
colorWarningTextActive: '#d48806',
|
||||
colorInfoBg: '#e6f4ff',
|
||||
colorInfoBgHover: '#bae0ff',
|
||||
colorInfoBorder: '#91caff',
|
||||
colorInfoBorderHover: '#69b1ff',
|
||||
colorInfoHover: '#69b1ff',
|
||||
colorInfoActive: '#0958d9',
|
||||
colorInfoTextHover: '#4096ff',
|
||||
colorInfoText: '#1677ff',
|
||||
colorInfoTextActive: '#0958d9',
|
||||
colorLinkActive: '#0958d9',
|
||||
colorBgMask: 'rgba(0, 0, 0, 0.45)',
|
||||
colorWhite: '#fff',
|
||||
fontSizeSM: 12,
|
||||
fontSizeLG: 16,
|
||||
fontSizeXL: 20,
|
||||
fontSizeHeading1: 38,
|
||||
fontSizeHeading2: 30,
|
||||
fontSizeHeading3: 24,
|
||||
fontSizeHeading4: 20,
|
||||
fontSizeHeading5: 16,
|
||||
lineHeight: 1.5714285714285714,
|
||||
lineHeightLG: 1.5,
|
||||
lineHeightSM: 1.6666666666666667,
|
||||
fontHeight: 22,
|
||||
fontHeightLG: 24,
|
||||
fontHeightSM: 20,
|
||||
lineHeightHeading1: 1.2105263157894737,
|
||||
lineHeightHeading2: 1.2666666666666666,
|
||||
lineHeightHeading3: 1.3333333333333333,
|
||||
lineHeightHeading4: 1.4,
|
||||
lineHeightHeading5: 1.5,
|
||||
sizeXXL: 48,
|
||||
sizeXL: 32,
|
||||
sizeLG: 24,
|
||||
sizeMD: 20,
|
||||
sizeMS: 16,
|
||||
size: 16,
|
||||
sizeSM: 12,
|
||||
sizeXS: 8,
|
||||
sizeXXS: 4,
|
||||
controlHeightSM: 24,
|
||||
controlHeightXS: 16,
|
||||
controlHeightLG: 40,
|
||||
motionDurationFast: '0.1s',
|
||||
motionDurationMid: '0.2s',
|
||||
motionDurationSlow: '0.3s',
|
||||
lineWidthBold: 2,
|
||||
borderRadiusXS: 2,
|
||||
borderRadiusSM: 4,
|
||||
borderRadiusLG: 8,
|
||||
borderRadiusOuter: 4,
|
||||
colorFillContent: 'rgba(0, 0, 0, 0.06)',
|
||||
colorFillContentHover: 'rgba(0, 0, 0, 0.15)',
|
||||
colorFillAlter: 'rgba(0, 0, 0, 0.02)',
|
||||
colorBgContainerDisabled: 'rgba(0, 0, 0, 0.04)',
|
||||
colorBorderBg: '#ffffff',
|
||||
colorSplit: 'rgba(5, 5, 5, 0.06)',
|
||||
colorTextPlaceholder: 'rgba(0, 0, 0, 0.25)',
|
||||
colorTextDisabled: 'rgba(0, 0, 0, 0.25)',
|
||||
colorTextHeading: 'rgba(0, 0, 0, 0.88)',
|
||||
colorTextLabel: 'rgba(0, 0, 0, 0.65)',
|
||||
colorTextDescription: 'rgba(0, 0, 0, 0.45)',
|
||||
colorTextLightSolid: '#fff',
|
||||
colorHighlight: '#ff4d4f',
|
||||
colorBgTextHover: 'rgba(0, 0, 0, 0.06)',
|
||||
colorBgTextActive: 'rgba(0, 0, 0, 0.15)',
|
||||
colorIcon: 'rgba(0, 0, 0, 0.45)',
|
||||
colorIconHover: 'rgba(0, 0, 0, 0.88)',
|
||||
colorErrorOutline: 'rgba(255, 38, 5, 0.06)',
|
||||
colorWarningOutline: 'rgba(255, 215, 5, 0.1)',
|
||||
fontSizeIcon: 12,
|
||||
lineWidthFocus: 3,
|
||||
controlOutlineWidth: 2,
|
||||
controlInteractiveSize: 16,
|
||||
controlItemBgHover: 'rgba(0, 0, 0, 0.04)',
|
||||
controlItemBgActive: '#eeebfa',
|
||||
controlItemBgActiveHover: '#e2dfed',
|
||||
controlItemBgActiveDisabled: 'rgba(0, 0, 0, 0.15)',
|
||||
controlTmpOutline: 'rgba(0, 0, 0, 0.02)',
|
||||
controlOutline: 'rgba(42, 5, 192, 0.08)',
|
||||
fontWeightStrong: 600,
|
||||
opacityLoading: 0.65,
|
||||
linkDecoration: 'none',
|
||||
linkHoverDecoration: 'none',
|
||||
linkFocusDecoration: 'none',
|
||||
controlPaddingHorizontal: 12,
|
||||
controlPaddingHorizontalSM: 8,
|
||||
paddingXXS: 4,
|
||||
paddingXS: 8,
|
||||
paddingSM: 12,
|
||||
padding: 16,
|
||||
paddingMD: 20,
|
||||
paddingLG: 24,
|
||||
paddingXL: 32,
|
||||
paddingContentHorizontalLG: 24,
|
||||
paddingContentVerticalLG: 16,
|
||||
paddingContentHorizontal: 16,
|
||||
paddingContentVertical: 12,
|
||||
paddingContentHorizontalSM: 16,
|
||||
paddingContentVerticalSM: 8,
|
||||
marginXXS: 4,
|
||||
marginXS: 8,
|
||||
marginSM: 12,
|
||||
margin: 16,
|
||||
marginMD: 20,
|
||||
marginLG: 24,
|
||||
marginXL: 32,
|
||||
marginXXL: 48,
|
||||
boxShadow:
|
||||
'\n 0 6px 16px 0 rgba(0, 0, 0, 0.08),\n 0 3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 9px 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowSecondary:
|
||||
'\n 0 6px 16px 0 rgba(0, 0, 0, 0.08),\n 0 3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 9px 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowTertiary:
|
||||
'\n 0 1px 2px 0 rgba(0, 0, 0, 0.03),\n 0 1px 6px -1px rgba(0, 0, 0, 0.02),\n 0 2px 4px 0 rgba(0, 0, 0, 0.02)\n ',
|
||||
screenXS: 480,
|
||||
screenXSMin: 480,
|
||||
screenXSMax: 575,
|
||||
screenSM: 576,
|
||||
screenSMMin: 576,
|
||||
screenSMMax: 767,
|
||||
screenMD: 768,
|
||||
screenMDMin: 768,
|
||||
screenMDMax: 991,
|
||||
screenLG: 992,
|
||||
screenLGMin: 992,
|
||||
screenLGMax: 1199,
|
||||
screenXL: 1200,
|
||||
screenXLMin: 1200,
|
||||
screenXLMax: 1599,
|
||||
screenXXL: 1600,
|
||||
screenXXLMin: 1600,
|
||||
boxShadowPopoverArrow: '2px 2px 5px rgba(0, 0, 0, 0.05)',
|
||||
boxShadowCard:
|
||||
'\n 0 1px 2px -2px rgba(0, 0, 0, 0.16),\n 0 3px 6px 0 rgba(0, 0, 0, 0.12),\n 0 5px 12px 4px rgba(0, 0, 0, 0.09)\n ',
|
||||
boxShadowDrawerRight:
|
||||
'\n -6px 0 16px 0 rgba(0, 0, 0, 0.08),\n -3px 0 6px -4px rgba(0, 0, 0, 0.12),\n -9px 0 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowDrawerLeft:
|
||||
'\n 6px 0 16px 0 rgba(0, 0, 0, 0.08),\n 3px 0 6px -4px rgba(0, 0, 0, 0.12),\n 9px 0 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowDrawerUp:
|
||||
'\n 0 6px 16px 0 rgba(0, 0, 0, 0.08),\n 0 3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 9px 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowDrawerDown:
|
||||
'\n 0 -6px 16px 0 rgba(0, 0, 0, 0.08),\n 0 -3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 -9px 28px 8px rgba(0, 0, 0, 0.05)\n ',
|
||||
boxShadowTabsOverflowLeft: 'inset 10px 0 8px -8px rgba(0, 0, 0, 0.08)',
|
||||
boxShadowTabsOverflowRight: 'inset -10px 0 8px -8px rgba(0, 0, 0, 0.08)',
|
||||
boxShadowTabsOverflowTop: 'inset 0 10px 8px -8px rgba(0, 0, 0, 0.08)',
|
||||
boxShadowTabsOverflowBottom: 'inset 0 -10px 8px -8px rgba(0, 0, 0, 0.08)',
|
||||
isDarkMode: false
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in globalVariables) {
|
||||
globalThis[key] = globalVariables[key]
|
||||
}
|
||||
@@ -4,13 +4,18 @@
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>Preview</title>
|
||||
<!-- es-module-shims -->
|
||||
<script id="global-js-variables">
|
||||
{{replace_global_js_variables}}
|
||||
</script>
|
||||
<style id="global-css-variables">
|
||||
{{replace_global_css_variables}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script type="module" id="appSrc">{{replace_code}}</script>
|
||||
<script type="module" id="appDictSrc">{{replace_dict_code}}</script>
|
||||
<script type="module" id="appBaseSrc">{{replace_base_code}}</script>
|
||||
<div id="root">
|
||||
<div
|
||||
style="position:absolute;top: 0;left:0;width:100%;height:100%;display: flex;justify-content: center;align-items: center;">
|
||||
<div style="position:absolute;top: 0;left:0;width:100%;height:100%;display: flex;justify-content: center;align-items: center;color: #777;">
|
||||
Loading...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -22,4 +22,30 @@ class ToolDataSource @Inject constructor(
|
||||
}
|
||||
)
|
||||
}.flowOn(ioDispatcher)
|
||||
|
||||
fun getGlobalJsVariables(isDarkMode: Boolean) = flow {
|
||||
emit(
|
||||
context.assets.open(
|
||||
if (isDarkMode) "template/global-variables-dark.js"
|
||||
else "template/global-variables-light.js"
|
||||
)
|
||||
.bufferedReader()
|
||||
.use {
|
||||
it.readText()
|
||||
}
|
||||
)
|
||||
}.flowOn(ioDispatcher)
|
||||
|
||||
fun getGlobalCssVariables(isDarkMode: Boolean) = flow {
|
||||
emit(
|
||||
context.assets.open(
|
||||
if (isDarkMode) "template/global-variables-dark.css"
|
||||
else "template/global-variables-light.css"
|
||||
)
|
||||
.bufferedReader()
|
||||
.use {
|
||||
it.readText()
|
||||
}
|
||||
)
|
||||
}.flowOn(ioDispatcher)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.Code
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Download
|
||||
import androidx.compose.material.icons.filled.Fullscreen
|
||||
import androidx.compose.material.icons.filled.FullscreenExit
|
||||
import androidx.compose.material.icons.filled.Inbox
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.filled.Reorder
|
||||
@@ -43,6 +45,8 @@ object OxygenIcons {
|
||||
val Delete = Icons.Default.Delete
|
||||
val Download = Icons.Default.Download
|
||||
val Error = Icons.Default.Cancel
|
||||
val FullScreen = Icons.Default.Fullscreen
|
||||
val FullScreenExit = Icons.Default.FullscreenExit
|
||||
val Home = Icons.Rounded.Home
|
||||
val HomeBorder = Icons.Outlined.Home
|
||||
val Info = Icons.Outlined.Info
|
||||
|
||||
@@ -57,14 +57,8 @@ internal class ConnectivityManagerNetworkMonitor @Inject constructor(
|
||||
}
|
||||
.conflate()
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun ConnectivityManager.isCurrentlyConnected() =
|
||||
when {
|
||||
VERSION.SDK_INT >= VERSION_CODES.M ->
|
||||
activeNetwork
|
||||
?.let(::getNetworkCapabilities)
|
||||
?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
|
||||
else -> activeNetworkInfo?.isConnected
|
||||
} ?: false
|
||||
?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package top.fatweb.oxygen.toolbox.navigation
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavDestination
|
||||
import androidx.navigation.compose.NavHost
|
||||
import top.fatweb.oxygen.toolbox.ui.OxygenAppState
|
||||
import top.fatweb.oxygen.toolbox.ui.util.LocalFullScreen
|
||||
|
||||
@Composable
|
||||
fun OxygenNavHost(
|
||||
@@ -16,6 +21,21 @@ fun OxygenNavHost(
|
||||
onShowSnackbar: suspend (message: String, action: String?) -> Boolean
|
||||
) {
|
||||
val navController = appState.navController
|
||||
val fullScreen = LocalFullScreen.current
|
||||
|
||||
LaunchedEffect(navController) {
|
||||
navController.addOnDestinationChangedListener(object :
|
||||
NavController.OnDestinationChangedListener {
|
||||
override fun onDestinationChanged(
|
||||
controller: NavController,
|
||||
destination: NavDestination,
|
||||
arguments: Bundle?
|
||||
) {
|
||||
fullScreen.onStateChange.invoke(false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
NavHost(
|
||||
modifier = modifier,
|
||||
navController = navController,
|
||||
|
||||
@@ -6,6 +6,10 @@ import top.fatweb.oxygen.toolbox.model.tool.ToolEntity
|
||||
interface ToolRepository {
|
||||
val toolViewTemplate: Flow<String>
|
||||
|
||||
fun getGlobalJsVariables(isDarkMode: Boolean): Flow<String>
|
||||
|
||||
fun getGlobalCssVariables(isDarkMode: Boolean): Flow<String>
|
||||
|
||||
fun getAllToolsStream(searchValue: String): Flow<List<ToolEntity>>
|
||||
|
||||
fun getStarToolsStream(searchValue: String): Flow<List<ToolEntity>>
|
||||
|
||||
@@ -14,6 +14,12 @@ class OfflineToolRepository @Inject constructor(
|
||||
override val toolViewTemplate: Flow<String>
|
||||
get() = toolDataSource.toolViewTemplate
|
||||
|
||||
override fun getGlobalJsVariables(isDarkMode: Boolean): Flow<String> =
|
||||
toolDataSource.getGlobalJsVariables(isDarkMode)
|
||||
|
||||
override fun getGlobalCssVariables(isDarkMode: Boolean): Flow<String> =
|
||||
toolDataSource.getGlobalCssVariables(isDarkMode)
|
||||
|
||||
override fun getAllToolsStream(searchValue: String): Flow<List<ToolEntity>> =
|
||||
toolDao.selectAllTools(searchValue)
|
||||
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
package top.fatweb.oxygen.toolbox.ui
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||
import androidx.compose.material3.BottomAppBar
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@@ -24,6 +20,8 @@ import androidx.compose.material3.SnackbarResult
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
@@ -34,7 +32,11 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.NavDestination
|
||||
import androidx.navigation.NavDestination.Companion.hierarchy
|
||||
@@ -57,6 +59,8 @@ import top.fatweb.oxygen.toolbox.ui.component.SearchButtonPosition
|
||||
import top.fatweb.oxygen.toolbox.ui.settings.SettingsDialog
|
||||
import top.fatweb.oxygen.toolbox.ui.theme.GradientColors
|
||||
import top.fatweb.oxygen.toolbox.ui.theme.LocalGradientColors
|
||||
import top.fatweb.oxygen.toolbox.ui.util.FullScreen
|
||||
import top.fatweb.oxygen.toolbox.ui.util.LocalFullScreen
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -67,6 +71,39 @@ fun OxygenApp(appState: OxygenAppState) {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
val context = LocalContext.current
|
||||
val window = (context as ComponentActivity).window
|
||||
val windowInsetsController = WindowInsetsControllerCompat(window, window.decorView)
|
||||
var isFullScreen by remember { mutableStateOf(false) }
|
||||
|
||||
val fullScreen = FullScreen(
|
||||
enable = isFullScreen,
|
||||
onStateChange = {
|
||||
isFullScreen = it
|
||||
}
|
||||
)
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
windowInsetsController.systemBarsBehavior =
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
val listener = WindowInsetsControllerCompat.OnControllableInsetsChangedListener { _, _ ->
|
||||
isFullScreen = false
|
||||
}
|
||||
windowInsetsController.addOnControllableInsetsChangedListener(listener)
|
||||
onDispose {
|
||||
windowInsetsController.removeOnControllableInsetsChangedListener(listener)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(isFullScreen) {
|
||||
if (isFullScreen) {
|
||||
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
|
||||
} else {
|
||||
windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
|
||||
}
|
||||
}
|
||||
|
||||
CompositionLocalProvider(LocalFullScreen provides fullScreen) {
|
||||
OxygenBackground {
|
||||
OxygenGradientBackground(
|
||||
gradientColors = if (shouldShowGradientBackground) LocalGradientColors.current else GradientColors()
|
||||
@@ -128,9 +165,6 @@ fun OxygenApp(appState: OxygenAppState) {
|
||||
bottomBar = {
|
||||
AnimatedVisibility(
|
||||
visible = appState.shouldShowBottomBar && destination != null
|
||||
) {
|
||||
BottomAppBar(
|
||||
windowInsets = WindowInsets(0)
|
||||
) {
|
||||
OxygenBottomBar(
|
||||
destinations = appState.topLevelDestinations,
|
||||
@@ -139,24 +173,19 @@ fun OxygenApp(appState: OxygenAppState) {
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
) { padding ->
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.consumeWindowInsets(padding)
|
||||
.windowInsetsPadding(
|
||||
WindowInsets.safeDrawing.only(
|
||||
WindowInsetsSides.Horizontal
|
||||
)
|
||||
)
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = appState.shouldShowNavRail && destination != null
|
||||
) {
|
||||
OxygenNavRail(
|
||||
modifier = Modifier.safeDrawingPadding(),
|
||||
modifier = Modifier
|
||||
.padding(padding)
|
||||
.consumeWindowInsets(padding)
|
||||
.safeDrawingPadding(),
|
||||
destinations = appState.topLevelDestinations,
|
||||
currentDestination = appState.currentDestination,
|
||||
onNavigateToDestination = appState::navigateToTopLevelDestination
|
||||
@@ -172,7 +201,13 @@ fun OxygenApp(appState: OxygenAppState) {
|
||||
OxygenTopAppBar(
|
||||
scrollBehavior = topAppBarScrollBehavior,
|
||||
title = {
|
||||
destination?.let { Text(text = stringResource(destination.titleTextId)) }
|
||||
destination?.let {
|
||||
Text(
|
||||
text = stringResource(destination.titleTextId),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
},
|
||||
navigationIcon = OxygenIcons.Search,
|
||||
navigationIconContentDescription = stringResource(R.string.feature_settings_top_app_bar_navigation_icon_description),
|
||||
@@ -224,6 +259,7 @@ fun OxygenApp(appState: OxygenAppState) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun OxygenBottomBar(
|
||||
@@ -295,5 +331,5 @@ private fun OxygenNavRail(
|
||||
|
||||
private fun NavDestination?.isTopLevelDestinationInHierarchy(destination: TopLevelDestination) =
|
||||
this?.hierarchy?.any {
|
||||
it.route?.equals(destination.route) ?: false
|
||||
} ?: false
|
||||
it.route?.equals(destination.route) == true
|
||||
} == true
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package top.fatweb.oxygen.toolbox.ui.about
|
||||
|
||||
import androidx.compose.animation.core.AnimationConstants
|
||||
import androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi
|
||||
import androidx.compose.animation.graphics.res.animatedVectorResource
|
||||
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
|
||||
import androidx.compose.animation.graphics.vector.AnimatedImageVector
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -13,6 +18,7 @@ import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
@@ -23,16 +29,21 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.delay
|
||||
import top.fatweb.oxygen.toolbox.R
|
||||
import top.fatweb.oxygen.toolbox.icon.OxygenIcons
|
||||
import top.fatweb.oxygen.toolbox.ui.component.OxygenTopAppBar
|
||||
@@ -86,7 +97,11 @@ internal fun AboutScreen(
|
||||
OxygenTopAppBar(
|
||||
scrollBehavior = topAppBarScrollBehavior,
|
||||
title = {
|
||||
Text(text = stringResource(R.string.feature_settings_more_about))
|
||||
Text(
|
||||
text = stringResource(R.string.feature_settings_more_about),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
},
|
||||
navigationIcon = OxygenIcons.Back,
|
||||
navigationIconContentDescription = stringResource(R.string.core_back),
|
||||
@@ -106,16 +121,26 @@ internal fun AboutScreen(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalAnimationGraphicsApi::class)
|
||||
@Composable
|
||||
private fun AboutAppInfo(
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val logo = AnimatedImageVector.animatedVectorResource(R.drawable.ic_launcher)
|
||||
var atEnd by remember { mutableStateOf(false) }
|
||||
LaunchedEffect(Unit) {
|
||||
delay(AnimationConstants.DefaultDurationMillis.toLong())
|
||||
atEnd = true
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = modifier,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Image(
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_oxygen),
|
||||
modifier = Modifier
|
||||
.width(160.dp),
|
||||
painter = rememberAnimatedVectorPainter(animatedImageVector = logo, atEnd = atEnd),
|
||||
contentDescription = stringResource(R.string.app_full_name)
|
||||
)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
@@ -136,8 +161,11 @@ private fun AboutAppInfo(
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.outline,
|
||||
text = "${ResourcesUtils.getAppVersionName(LocalContext.current)} (${
|
||||
ResourcesUtils.getAppVersionCode(
|
||||
LocalContext.current
|
||||
stringResource(
|
||||
if (ResourcesUtils.getAppVersionCode(LocalContext.current) % 100 == 0L)
|
||||
R.string.core_ga_version
|
||||
else
|
||||
R.string.core_beta_version
|
||||
)
|
||||
})"
|
||||
)
|
||||
|
||||
@@ -47,6 +47,7 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
@@ -132,7 +133,11 @@ internal fun LibrariesScreen(
|
||||
OxygenTopAppBar(
|
||||
scrollBehavior = topAppBarScrollBehavior,
|
||||
title = {
|
||||
Text(text = stringResource(R.string.feature_settings_open_source_license))
|
||||
Text(
|
||||
text = stringResource(R.string.feature_settings_open_source_license),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
},
|
||||
navigationIcon = OxygenIcons.Back,
|
||||
navigationIconContentDescription = stringResource(R.string.core_back),
|
||||
@@ -159,7 +164,7 @@ internal fun LibrariesScreen(
|
||||
onSearch("")
|
||||
}
|
||||
)
|
||||
Box(modifier = Modifier) {
|
||||
Box {
|
||||
when (librariesScreenUiState) {
|
||||
LibrariesScreenUiState.Loading -> {
|
||||
Indicator()
|
||||
@@ -247,10 +252,7 @@ internal fun LibrariesScreen(
|
||||
Column(
|
||||
modifier = Modifier.verticalScroll(state = rememberScrollState())
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier,
|
||||
text = dialogContent
|
||||
)
|
||||
Text(text = dialogContent)
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package top.fatweb.oxygen.toolbox.ui.component
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.text.ClickableText
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.LinkAnnotation
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.withStyle
|
||||
@@ -14,7 +15,7 @@ import top.fatweb.oxygen.toolbox.ui.util.ResourcesUtils
|
||||
fun ClickableText(
|
||||
@StringRes text: Int,
|
||||
@StringRes replaceText: Int,
|
||||
onClick: (Int) -> Unit
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val primaryColor = MaterialTheme.colorScheme.primary
|
||||
@@ -30,7 +31,10 @@ fun ClickableText(
|
||||
clickablePart
|
||||
)
|
||||
append(mainText.substringBefore(clickablePart))
|
||||
pushStringAnnotation(tag = "Click", annotation = clickablePart)
|
||||
pushLink(LinkAnnotation.Clickable(
|
||||
tag = "Click",
|
||||
linkInteractionListener = { onClick() }
|
||||
))
|
||||
withStyle(style = SpanStyle(color = primaryColor)) {
|
||||
append(clickablePart)
|
||||
}
|
||||
@@ -38,5 +42,5 @@ fun ClickableText(
|
||||
append(mainText.substringAfter(clickablePart))
|
||||
}
|
||||
|
||||
ClickableText(text = annotatedString, onClick = onClick)
|
||||
Text(text = annotatedString)
|
||||
}
|
||||
@@ -33,6 +33,8 @@ import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import top.fatweb.oxygen.toolbox.R
|
||||
import top.fatweb.oxygen.toolbox.icon.OxygenIcons
|
||||
@@ -44,6 +46,7 @@ import android.R as androidR
|
||||
@Composable
|
||||
fun OxygenTopAppBar(
|
||||
modifier: Modifier = Modifier,
|
||||
expandedHeight: Dp = 48.dp,
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null,
|
||||
title: @Composable () -> Unit = {},
|
||||
navigationIcon: ImageVector? = null,
|
||||
@@ -61,8 +64,12 @@ fun OxygenTopAppBar(
|
||||
onCancelSearch: () -> Unit = {}
|
||||
) {
|
||||
val topInset by animateIntAsState(
|
||||
if (scrollBehavior != null && -scrollBehavior.state.heightOffset >= with(LocalDensity.current) { 64.0.dp.toPx() }) 0
|
||||
else TopAppBarDefaults.windowInsets.getTop(LocalDensity.current), label = ""
|
||||
targetValue = if (scrollBehavior != null && -scrollBehavior.state.heightOffset >= with(
|
||||
LocalDensity.current
|
||||
) { expandedHeight.toPx() }
|
||||
) 0
|
||||
else TopAppBarDefaults.windowInsets.getTop(LocalDensity.current),
|
||||
label = ""
|
||||
)
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
@@ -81,6 +88,7 @@ fun OxygenTopAppBar(
|
||||
CenterAlignedTopAppBar(
|
||||
modifier = modifier,
|
||||
scrollBehavior = scrollBehavior,
|
||||
expandedHeight = expandedHeight,
|
||||
title = {
|
||||
if (activeSearch) TextField(
|
||||
modifier = Modifier
|
||||
@@ -116,6 +124,7 @@ fun OxygenTopAppBar(
|
||||
},
|
||||
maxLines = 1,
|
||||
singleLine = true,
|
||||
textStyle = MaterialTheme.typography.titleSmall,
|
||||
onValueChange = {
|
||||
if ("\n" !in it) onQueryChange(it)
|
||||
}
|
||||
@@ -175,7 +184,13 @@ enum class SearchButtonPosition {
|
||||
private fun OxygenTopAppBarPreview() {
|
||||
OxygenTheme {
|
||||
OxygenTopAppBar(
|
||||
title = { Text(text = stringResource(androidR.string.untitled)) },
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(androidR.string.untitled),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
},
|
||||
navigationIcon = OxygenIcons.Search,
|
||||
navigationIconContentDescription = "Navigation icon",
|
||||
actionIcon = OxygenIcons.MoreVert,
|
||||
|
||||
@@ -167,7 +167,6 @@ private fun ToolAction(
|
||||
.padding(horizontal = 6.dp, vertical = 6.dp)
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier,
|
||||
imageVector = actionIcon,
|
||||
contentDescription = actionIconContentDescription
|
||||
)
|
||||
|
||||
@@ -221,7 +221,7 @@ fun Scrollbar(
|
||||
withTimeout(viewConfiguration.longPressTimeoutMillis) {
|
||||
tryAwaitRelease()
|
||||
}
|
||||
} catch (e: TimeoutCancellationException) {
|
||||
} catch (_: TimeoutCancellationException) {
|
||||
// Start the press triggered scroll
|
||||
val initialPress = PressInteraction.Press(offset)
|
||||
interactionSource?.tryEmit(initialPress)
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.widget.Toast
|
||||
import androidx.activity.compose.ReportDrawnWhen
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
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
|
||||
@@ -33,7 +32,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshContainer
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
||||
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -44,8 +43,6 @@ 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.clipToBounds
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -114,15 +111,11 @@ internal fun ToolStoreScreen(
|
||||
|
||||
ReportDrawnWhen { !isToolLoading }
|
||||
|
||||
val pullToRefreshState = rememberPullToRefreshState()
|
||||
LaunchedEffect(pullToRefreshState.isRefreshing) {
|
||||
if (pullToRefreshState.isRefreshing) {
|
||||
toolStorePagingItems.refresh()
|
||||
}
|
||||
}
|
||||
var isRefreshing by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(toolStorePagingItems.loadState.refresh) {
|
||||
if (toolStorePagingItems.loadState.refresh != LoadState.Loading) {
|
||||
pullToRefreshState.endRefresh()
|
||||
if (toolStorePagingItems.loadState.refresh != LoadState.Loading && isRefreshing) {
|
||||
isRefreshing = false
|
||||
}
|
||||
if (toolStorePagingItems.loadState.refresh is LoadState.Error) {
|
||||
Toast.makeText(
|
||||
@@ -136,6 +129,12 @@ internal fun ToolStoreScreen(
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(isRefreshing) {
|
||||
if (isRefreshing) {
|
||||
toolStorePagingItems.refresh()
|
||||
}
|
||||
}
|
||||
|
||||
val itemsAvailable = toolStorePagingItems.itemCount
|
||||
|
||||
val state = rememberLazyStaggeredGridState()
|
||||
@@ -151,11 +150,14 @@ internal fun ToolStoreScreen(
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier
|
||||
.fillMaxSize()
|
||||
.clipToBounds()
|
||||
.nestedScroll(pullToRefreshState.nestedScrollConnection)
|
||||
PullToRefreshBox(
|
||||
modifier = modifier
|
||||
.fillMaxSize(),
|
||||
state = rememberPullToRefreshState(),
|
||||
isRefreshing = isRefreshing,
|
||||
onRefresh = {
|
||||
isRefreshing = true
|
||||
}
|
||||
) {
|
||||
if (itemsAvailable > 0 || (toolStorePagingItems.loadState.refresh == LoadState.Loading && itemsAvailable == 0)) {
|
||||
LazyVerticalStaggeredGrid(
|
||||
@@ -232,12 +234,6 @@ internal fun ToolStoreScreen(
|
||||
}
|
||||
}
|
||||
|
||||
PullToRefreshContainer(
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopCenter),
|
||||
state = pullToRefreshState,
|
||||
)
|
||||
|
||||
state.DraggableScrollbar(
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
|
||||
@@ -204,7 +204,7 @@ fun supportsDynamicTheming() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||
uiMode = Configuration.UI_MODE_NIGHT_YES or Configuration.UI_MODE_TYPE_NORMAL
|
||||
)
|
||||
@Preview(
|
||||
name = "Api 21 Light", group = "ApiLevelPreviews", apiLevel = 21,
|
||||
name = "Api 24 Light", group = "ApiLevelPreviews", apiLevel = 24,
|
||||
uiMode = Configuration.UI_MODE_NIGHT_NO or Configuration.UI_MODE_TYPE_NORMAL
|
||||
)
|
||||
annotation class OxygenPreviews
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package top.fatweb.oxygen.toolbox.ui.util
|
||||
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
|
||||
data class FullScreen(
|
||||
val enable: Boolean = false,
|
||||
val onStateChange: (Boolean) -> Unit = {}
|
||||
)
|
||||
|
||||
val LocalFullScreen = compositionLocalOf { FullScreen() }
|
||||
@@ -2,9 +2,7 @@ package top.fatweb.oxygen.toolbox.ui.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.LocaleList
|
||||
import androidx.annotation.RequiresApi
|
||||
import top.fatweb.oxygen.toolbox.model.userdata.LanguageConfig
|
||||
import java.util.Locale
|
||||
|
||||
@@ -24,11 +22,7 @@ object LocaleUtils {
|
||||
fun attachBaseContext(context: Context, languageConfig: LanguageConfig): Context {
|
||||
val locale: Locale = getLocaleFromLanguageConfig(languageConfig)
|
||||
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
createConfigurationContext(context, locale)
|
||||
} else {
|
||||
updateConfiguration(context, locale)
|
||||
}
|
||||
return createConfigurationContext(context, locale)
|
||||
}
|
||||
|
||||
private fun getLocaleFromLanguageConfig(languageConfig: LanguageConfig): Locale =
|
||||
@@ -38,21 +32,10 @@ object LocaleUtils {
|
||||
LanguageConfig.English -> Locale("en")
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
private fun createConfigurationContext(context: Context, locale: Locale): Context {
|
||||
val configuration = context.resources.configuration
|
||||
configuration.setLocales(LocaleList(locale))
|
||||
|
||||
return context.createConfigurationContext(configuration)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun updateConfiguration(context: Context, locale: Locale): Context {
|
||||
val resources = context.resources
|
||||
val configuration = resources.configuration
|
||||
configuration.locale = locale
|
||||
resources.updateConfiguration(configuration, resources.displayMetrics)
|
||||
|
||||
return context
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package top.fatweb.oxygen.toolbox.ui.util
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import android.os.Build
|
||||
import androidx.annotation.StringRes
|
||||
@@ -10,14 +11,9 @@ import androidx.core.os.LocaleListCompat
|
||||
import java.util.Locale
|
||||
|
||||
object ResourcesUtils {
|
||||
fun getConfiguration(context: Context) = context.resources.configuration
|
||||
fun getConfiguration(context: Context): Configuration = context.resources.configuration
|
||||
|
||||
fun getDisplayMetrics(context: Context) = context.resources.displayMetrics
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
fun getAppLocale(context: Context): Locale =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) getConfiguration(context).locales.get(0)
|
||||
else getConfiguration(context).locale
|
||||
fun getAppLocale(context: Context): Locale = getConfiguration(context).locales.get(0)
|
||||
|
||||
fun getSystemLocale(): LocaleListCompat =
|
||||
ConfigurationCompat.getLocales(Resources.getSystem().configuration)
|
||||
@@ -25,7 +21,7 @@ object ResourcesUtils {
|
||||
fun getAppVersionName(context: Context): String =
|
||||
try {
|
||||
context.packageManager.getPackageInfo(context.packageName, 0)?.versionName ?: "Unknown"
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
} catch (_: PackageManager.NameNotFoundException) {
|
||||
"Unknown"
|
||||
}
|
||||
|
||||
@@ -38,7 +34,7 @@ object ResourcesUtils {
|
||||
context.packageName,
|
||||
0
|
||||
)?.versionCode?.toLong() ?: -1
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
} catch (_: PackageManager.NameNotFoundException) {
|
||||
-1
|
||||
}
|
||||
|
||||
|
||||
@@ -1,32 +1,56 @@
|
||||
package top.fatweb.oxygen.toolbox.ui.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.DownloadManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import android.webkit.ConsoleMessage
|
||||
import android.webkit.JsPromptResult
|
||||
import android.webkit.JsResult
|
||||
import android.webkit.ValueCallback
|
||||
import android.webkit.WebView
|
||||
import androidx.activity.compose.ManagedActivityResultLauncher
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
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.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.kevinnzou.web.AccompanistWebChromeClient
|
||||
@@ -37,7 +61,11 @@ import top.fatweb.oxygen.toolbox.R
|
||||
import top.fatweb.oxygen.toolbox.icon.OxygenIcons
|
||||
import top.fatweb.oxygen.toolbox.ui.component.Indicator
|
||||
import top.fatweb.oxygen.toolbox.ui.component.OxygenTopAppBar
|
||||
import top.fatweb.oxygen.toolbox.ui.util.LocalFullScreen
|
||||
import top.fatweb.oxygen.toolbox.ui.util.ResourcesUtils
|
||||
import top.fatweb.oxygen.toolbox.util.NativeWebApi
|
||||
import top.fatweb.oxygen.toolbox.util.Permissions
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
@Composable
|
||||
internal fun ToolViewRoute(
|
||||
@@ -45,12 +73,14 @@ internal fun ToolViewRoute(
|
||||
viewModel: ToolViewScreenViewModel = hiltViewModel(),
|
||||
onBackClick: () -> Unit
|
||||
) {
|
||||
val isPreview by viewModel.isPreview.collectAsStateWithLifecycle()
|
||||
val toolViewUiState by viewModel.toolViewUiState.collectAsStateWithLifecycle()
|
||||
val webViewInstanceState by viewModel.webviewInstance.collectAsStateWithLifecycle()
|
||||
val isPreview by viewModel.isPreview.collectAsStateWithLifecycle()
|
||||
|
||||
ToolViewScreen(
|
||||
modifier = modifier,
|
||||
toolViewUiState = toolViewUiState,
|
||||
webViewInstanceState = webViewInstanceState,
|
||||
isPreview = isPreview,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
@@ -62,28 +92,38 @@ internal fun ToolViewRoute(
|
||||
internal fun ToolViewScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
toolViewUiState: ToolViewUiState,
|
||||
webViewInstanceState: WebViewInstanceState,
|
||||
isPreview: Boolean,
|
||||
onBackClick: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val (isFullScreen, onFullScreenStateChange) = LocalFullScreen.current
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier,
|
||||
containerColor = Color.Transparent,
|
||||
contentWindowInsets = WindowInsets(left = 0, top = 0, right = 0, bottom = 0)
|
||||
) { padding ->
|
||||
Column(
|
||||
modifier
|
||||
.fillMaxWidth()
|
||||
.padding(padding)
|
||||
.consumeWindowInsets(padding)
|
||||
.windowInsetsPadding(
|
||||
WindowInsets.safeDrawing.only(
|
||||
WindowInsetsSides.Horizontal
|
||||
Column(modifier.fillMaxWidth()) {
|
||||
AnimatedVisibility(!isFullScreen) {
|
||||
TopBar(
|
||||
toolViewUiState = toolViewUiState,
|
||||
isPreview = isPreview,
|
||||
isFullScreen = isFullScreen,
|
||||
onBackClick = onBackClick,
|
||||
onFullScreenChange = onFullScreenStateChange
|
||||
)
|
||||
}
|
||||
Content(
|
||||
toolViewUiState = toolViewUiState,
|
||||
webViewInstanceState = webViewInstanceState
|
||||
)
|
||||
) {
|
||||
OxygenTopAppBar(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun TopBar(
|
||||
toolViewUiState: ToolViewUiState,
|
||||
isPreview: Boolean,
|
||||
isFullScreen: Boolean,
|
||||
onBackClick: () -> Unit,
|
||||
onFullScreenChange: (Boolean) -> Unit
|
||||
) = OxygenTopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
text = when (toolViewUiState) {
|
||||
@@ -93,17 +133,51 @@ internal fun ToolViewScreen(
|
||||
R.string.feature_tool_view_preview_suffix,
|
||||
toolViewUiState.toolName
|
||||
) else toolViewUiState.toolName
|
||||
}
|
||||
},
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
},
|
||||
navigationIcon = OxygenIcons.Back,
|
||||
navigationIconContentDescription = stringResource(R.string.core_back),
|
||||
actionIcon = if (isFullScreen) OxygenIcons.FullScreenExit else OxygenIcons.FullScreen,
|
||||
actionIconContentDescription = stringResource(if (isFullScreen) R.string.core_exit_full_screen else R.string.core_full_screen),
|
||||
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
|
||||
containerColor = Color.Transparent,
|
||||
scrolledContainerColor = Color.Transparent
|
||||
),
|
||||
onNavigationClick = onBackClick
|
||||
onNavigationClick = onBackClick,
|
||||
onActionClick = {
|
||||
onFullScreenChange(!isFullScreen)
|
||||
}
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun Content(
|
||||
toolViewUiState: ToolViewUiState,
|
||||
webViewInstanceState: WebViewInstanceState
|
||||
) {
|
||||
val configuration = LocalConfiguration.current
|
||||
val context = LocalContext.current
|
||||
|
||||
var fileChooserCallback by remember { mutableStateOf<ValueCallback<Array<Uri>>?>(null) }
|
||||
val fileChooserLauncher = rememberFileChooserLauncher(fileChooserCallback)
|
||||
val permissionLauncher = rememberPermissionLauncher()
|
||||
|
||||
var isShowDialog = remember { mutableStateOf(false) }
|
||||
var dialogType = remember { mutableStateOf(DialogType.Alert) }
|
||||
var dialogTitle by remember { mutableStateOf("") }
|
||||
var dialogText = remember { mutableStateOf("") }
|
||||
var dialogInputValue = remember { mutableStateOf("") }
|
||||
var onDialogConfirm = remember { mutableStateOf<((String) -> Unit)?>(null) }
|
||||
var onDialogCancel = remember { mutableStateOf<(() -> Unit)?>(null) }
|
||||
|
||||
when (webViewInstanceState) {
|
||||
WebViewInstanceState.Loading -> {
|
||||
Indicator()
|
||||
}
|
||||
|
||||
is WebViewInstanceState.Success -> {
|
||||
when (toolViewUiState) {
|
||||
ToolViewUiState.Loading -> {
|
||||
Indicator()
|
||||
@@ -120,6 +194,7 @@ internal fun ToolViewScreen(
|
||||
}
|
||||
|
||||
is ToolViewUiState.Success -> {
|
||||
dialogTitle = toolViewUiState.toolName
|
||||
val webViewState = rememberWebViewStateWithHTMLData(
|
||||
data = toolViewUiState.htmlData,
|
||||
)
|
||||
@@ -128,7 +203,155 @@ internal fun ToolViewScreen(
|
||||
.fillMaxSize()
|
||||
.imePadding(),
|
||||
state = webViewState,
|
||||
chromeClient = remember {
|
||||
chromeClient = rememberChromeClient(
|
||||
context = context,
|
||||
fileChooserLauncher = fileChooserLauncher,
|
||||
isShowDialog = isShowDialog,
|
||||
dialogType = dialogType,
|
||||
dialogText = dialogText,
|
||||
dialogInputValue = dialogInputValue,
|
||||
onDialogConfirm = onDialogConfirm,
|
||||
onDialogCancel = onDialogCancel
|
||||
) {
|
||||
fileChooserCallback = it
|
||||
},
|
||||
onCreated = initWebView(
|
||||
context = context,
|
||||
permissionLauncher = permissionLauncher
|
||||
),
|
||||
factory = {
|
||||
webViewInstanceState.webView
|
||||
},
|
||||
captureBackPresses = false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isShowDialog.value) {
|
||||
AlertDialog(
|
||||
modifier = Modifier
|
||||
.widthIn(max = configuration.screenWidthDp.dp - 80.dp)
|
||||
.heightIn(max = configuration.screenHeightDp.dp - 40.dp),
|
||||
onDismissRequest = {},
|
||||
title = {
|
||||
Text(
|
||||
text = dialogTitle,
|
||||
style = MaterialTheme.typography.titleLarge
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Column {
|
||||
Column(
|
||||
modifier = Modifier.verticalScroll(state = rememberScrollState())
|
||||
) {
|
||||
Text(text = dialogText.value)
|
||||
}
|
||||
if (dialogType.value == DialogType.Prompt) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
TextField(
|
||||
value = dialogInputValue.value,
|
||||
onValueChange = {
|
||||
dialogInputValue.value = it
|
||||
},
|
||||
textStyle = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
TextButton(onClick = {
|
||||
isShowDialog.value = false
|
||||
onDialogConfirm.value?.invoke(dialogInputValue.value)
|
||||
}) {
|
||||
Text(text = stringResource(R.string.core_ok))
|
||||
}
|
||||
if (dialogType.value != DialogType.Alert) {
|
||||
TextButton(onClick = {
|
||||
isShowDialog.value = false
|
||||
onDialogCancel.value?.invoke()
|
||||
}) {
|
||||
Text(text = stringResource(R.string.core_cancel))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberFileChooserLauncher(fileChooserCallback: ValueCallback<Array<Uri>>?) =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode == Activity.RESULT_OK) {
|
||||
it.data?.data?.let { uri ->
|
||||
fileChooserCallback?.onReceiveValue(arrayOf(uri))
|
||||
} ?: {
|
||||
fileChooserCallback?.onReceiveValue(emptyArray())
|
||||
}
|
||||
} else {
|
||||
fileChooserCallback?.onReceiveValue(emptyArray())
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberPermissionLauncher() =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {
|
||||
Permissions.continuation?.resume(it)
|
||||
}
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
private fun initWebView(
|
||||
context: Context,
|
||||
permissionLauncher: ManagedActivityResultLauncher<String, Boolean>
|
||||
) = { webview: WebView ->
|
||||
webview.setBackgroundColor(Color.Transparent.toArgb())
|
||||
webview.settings.javaScriptEnabled = true
|
||||
webview.settings.domStorageEnabled = true
|
||||
webview.addJavascriptInterface(
|
||||
NativeWebApi(context = context, permissionLauncher = permissionLauncher),
|
||||
"NativeApi"
|
||||
)
|
||||
webview.setDownloadListener { url, userAgent, _, mimetype, _ ->
|
||||
if (!listOf("http://", "https://").any(url::startsWith)) {
|
||||
webview.evaluateJavascript(
|
||||
"alert('${
|
||||
ResourcesUtils.getString(
|
||||
context = context,
|
||||
resId = R.string.core_can_only_download_http_https,
|
||||
url
|
||||
)
|
||||
}')"
|
||||
) {}
|
||||
return@setDownloadListener
|
||||
}
|
||||
val request = DownloadManager.Request(Uri.parse(url)).apply {
|
||||
addRequestHeader("User-Agent", userAgent)
|
||||
setMimeType(mimetype)
|
||||
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
|
||||
}
|
||||
val downloadManager: DownloadManager =
|
||||
context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
|
||||
downloadManager.enqueue(request)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberChromeClient(
|
||||
context: Context,
|
||||
fileChooserLauncher: ManagedActivityResultLauncher<Intent, ActivityResult>,
|
||||
isShowDialog: MutableState<Boolean>,
|
||||
dialogType: MutableState<DialogType>,
|
||||
dialogText: MutableState<String>,
|
||||
dialogInputValue: MutableState<String>,
|
||||
onDialogConfirm: MutableState<((String) -> Unit)?>,
|
||||
onDialogCancel: MutableState<(() -> Unit)?>,
|
||||
processCallback: (ValueCallback<Array<Uri>>?) -> Unit
|
||||
) = remember {
|
||||
object : AccompanistWebChromeClient() {
|
||||
override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
|
||||
consoleMessage?.let {
|
||||
@@ -146,19 +369,89 @@ internal fun ToolViewScreen(
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onShowFileChooser(
|
||||
webView: WebView?,
|
||||
filePathCallback: ValueCallback<Array<Uri>>?,
|
||||
fileChooserParams: FileChooserParams?
|
||||
): Boolean {
|
||||
processCallback(filePathCallback)
|
||||
val intent = fileChooserParams?.createIntent()
|
||||
?: Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = "*/*"
|
||||
}
|
||||
},
|
||||
onCreated = {
|
||||
it.settings.javaScriptEnabled = true
|
||||
it.settings.domStorageEnabled = true
|
||||
it.addJavascriptInterface(
|
||||
NativeWebApi(context = context, webView = it),
|
||||
"NativeApi"
|
||||
fileChooserLauncher.launch(
|
||||
Intent.createChooser(
|
||||
intent,
|
||||
fileChooserParams?.title ?: ResourcesUtils.getString(
|
||||
context = context,
|
||||
resId = R.string.core_file_select_one_text
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onJsAlert(
|
||||
view: WebView?,
|
||||
url: String?,
|
||||
message: String?,
|
||||
result: JsResult?
|
||||
): Boolean {
|
||||
isShowDialog.value = true
|
||||
dialogType.value = DialogType.Alert
|
||||
dialogText.value = message ?: ""
|
||||
onDialogConfirm.value = {
|
||||
result?.confirm()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onJsConfirm(
|
||||
view: WebView?,
|
||||
url: String?,
|
||||
message: String?,
|
||||
result: JsResult?
|
||||
): Boolean {
|
||||
isShowDialog.value = true
|
||||
dialogType.value = DialogType.Confirm
|
||||
dialogText.value = message ?: ""
|
||||
onDialogConfirm.value = {
|
||||
result?.confirm()
|
||||
}
|
||||
onDialogCancel.value = {
|
||||
result?.cancel()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onJsPrompt(
|
||||
view: WebView?,
|
||||
url: String?,
|
||||
message: String?,
|
||||
defaultValue: String?,
|
||||
result: JsPromptResult?
|
||||
): Boolean {
|
||||
isShowDialog.value = true
|
||||
dialogType.value = DialogType.Prompt
|
||||
dialogText.value = message ?: ""
|
||||
dialogInputValue.value = defaultValue ?: ""
|
||||
onDialogConfirm.value = {
|
||||
result?.confirm(dialogInputValue.value)
|
||||
}
|
||||
onDialogCancel.value = {
|
||||
result?.cancel()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum class DialogType {
|
||||
Alert, Confirm, Prompt
|
||||
}
|
||||
|
||||
@@ -1,21 +1,38 @@
|
||||
package top.fatweb.oxygen.toolbox.ui.view
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.res.Configuration
|
||||
import android.webkit.WebView
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.FlowCollector
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import timber.log.Timber
|
||||
import top.fatweb.oxygen.toolbox.model.Result
|
||||
import top.fatweb.oxygen.toolbox.model.tool.ToolEntity
|
||||
import top.fatweb.oxygen.toolbox.model.userdata.DarkThemeConfig
|
||||
import top.fatweb.oxygen.toolbox.navigation.ToolViewArgs
|
||||
import top.fatweb.oxygen.toolbox.repository.tool.StoreRepository
|
||||
import top.fatweb.oxygen.toolbox.repository.tool.ToolRepository
|
||||
import top.fatweb.oxygen.toolbox.repository.userdata.UserDataRepository
|
||||
import top.fatweb.oxygen.toolbox.ui.util.ResourcesUtils
|
||||
import top.fatweb.oxygen.toolbox.util.decodeToStringWithZip
|
||||
import javax.inject.Inject
|
||||
import kotlin.io.encoding.Base64
|
||||
@@ -24,6 +41,8 @@ import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@HiltViewModel
|
||||
class ToolViewScreenViewModel @Inject constructor(
|
||||
@ApplicationContext context: Context,
|
||||
userDataRepository: UserDataRepository,
|
||||
storeRepository: StoreRepository,
|
||||
toolRepository: ToolRepository,
|
||||
savedStateHandle: SavedStateHandle
|
||||
@@ -35,64 +54,103 @@ class ToolViewScreenViewModel @Inject constructor(
|
||||
private val toolId = toolViewArgs.toolId
|
||||
private val preview = toolViewArgs.preview
|
||||
|
||||
private val storeDetailCache = MutableStateFlow<Result<ToolEntity>?>(null)
|
||||
|
||||
|
||||
val toolViewUiState: StateFlow<ToolViewUiState> = toolViewUiState(
|
||||
context = context,
|
||||
savedStateHandle = savedStateHandle,
|
||||
username = username,
|
||||
toolId = toolId,
|
||||
preview = preview,
|
||||
userDataRepository = userDataRepository,
|
||||
storeRepository = storeRepository,
|
||||
toolRepository = toolRepository
|
||||
toolRepository = toolRepository,
|
||||
storeDetailCache = storeDetailCache
|
||||
)
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
initialValue = ToolViewUiState.Loading,
|
||||
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5.seconds.inWholeMilliseconds)
|
||||
)
|
||||
|
||||
val webviewInstance = flow<WebViewInstanceState> {
|
||||
val webviewInstance = WebView(context)
|
||||
emit(WebViewInstanceState.Success(webviewInstance))
|
||||
}.stateIn(
|
||||
viewModelScope,
|
||||
initialValue = WebViewInstanceState.Loading,
|
||||
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5.seconds.inWholeMilliseconds)
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private fun toolViewUiState(
|
||||
context: Context,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
username: String,
|
||||
toolId: String,
|
||||
preview: Boolean,
|
||||
userDataRepository: UserDataRepository,
|
||||
storeRepository: StoreRepository,
|
||||
toolRepository: ToolRepository
|
||||
toolRepository: ToolRepository,
|
||||
storeDetailCache: MutableStateFlow<Result<ToolEntity>?>
|
||||
): Flow<ToolViewUiState> {
|
||||
val toolViewTemplate = toolRepository.toolViewTemplate
|
||||
val entityFlow =
|
||||
if (!preview) toolRepository.getToolByUsernameAndToolId(username, toolId) else flowOf(null)
|
||||
|
||||
return flow {
|
||||
combine(entityFlow, toolViewTemplate, ::Pair).collect { (entityFlow, toolViewTemplate) ->
|
||||
val isSystemDarkModeFlow = callbackFlow<Boolean> {
|
||||
val receiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, instent: Intent?) {
|
||||
context?.let(ResourcesUtils::getConfiguration)?.run {
|
||||
trySend((uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES)
|
||||
}
|
||||
}
|
||||
}
|
||||
val filter = IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED)
|
||||
context.registerReceiver(receiver, filter)
|
||||
|
||||
trySend((ResourcesUtils.getConfiguration(context).uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES)
|
||||
|
||||
awaitClose { context.unregisterReceiver(receiver) }
|
||||
}
|
||||
|
||||
return isSystemDarkModeFlow.flatMapLatest { isSystemDarkMode ->
|
||||
flow {
|
||||
userDataRepository.userData.collect { userData ->
|
||||
val isDarkMode: Boolean = when (userData.darkThemeConfig) {
|
||||
DarkThemeConfig.FollowSystem -> isSystemDarkMode
|
||||
DarkThemeConfig.Light -> false
|
||||
DarkThemeConfig.Dark -> true
|
||||
}
|
||||
val globalJsVariables = toolRepository.getGlobalJsVariables(isDarkMode)
|
||||
val globalCssVariables = toolRepository.getGlobalCssVariables(isDarkMode)
|
||||
combine(entityFlow, toolViewTemplate, globalJsVariables, ::Triple)
|
||||
.combine(globalCssVariables) { triple, globalCssVariables ->
|
||||
Quadruple(triple.first, triple.second, triple.third, globalCssVariables)
|
||||
}
|
||||
.collect { (entityFlow, toolViewTemplate, globalJsVariables, globalCssVariables) ->
|
||||
if (entityFlow == null) {
|
||||
savedStateHandle[IS_PREVIEW] = true
|
||||
storeRepository.detail(username, toolId).collect {
|
||||
emit(
|
||||
when (it) {
|
||||
is Result.Success -> {
|
||||
val dist = it.data.dist!!
|
||||
val base = it.data.base!!
|
||||
ToolViewUiState.Success(
|
||||
it.data.name,
|
||||
processHtml(
|
||||
val cachedDetail = storeDetailCache.value
|
||||
if (cachedDetail != null) {
|
||||
emitResult(
|
||||
result = cachedDetail,
|
||||
toolViewTemplate = toolViewTemplate,
|
||||
distBase64 = dist,
|
||||
baseBase64 = base
|
||||
globalJsVariables = globalJsVariables,
|
||||
globalCssVariables = globalCssVariables
|
||||
)
|
||||
} else {
|
||||
storeRepository.detail(username, toolId).collect { result ->
|
||||
storeDetailCache.value = result
|
||||
emitResult(
|
||||
result = result,
|
||||
toolViewTemplate = toolViewTemplate,
|
||||
globalJsVariables = globalJsVariables,
|
||||
globalCssVariables = globalCssVariables
|
||||
)
|
||||
}
|
||||
|
||||
is Result.Loading -> ToolViewUiState.Loading
|
||||
is Result.Error -> {
|
||||
Timber.e("Can not load tool", it.exception)
|
||||
|
||||
ToolViewUiState.Error
|
||||
}
|
||||
|
||||
is Result.Fail -> ToolViewUiState.Error
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
savedStateHandle[IS_PREVIEW] = false
|
||||
@@ -101,6 +159,8 @@ private fun toolViewUiState(
|
||||
entityFlow.name,
|
||||
processHtml(
|
||||
toolViewTemplate = toolViewTemplate,
|
||||
globalJsVariables = globalJsVariables,
|
||||
globalCssVariables = globalCssVariables,
|
||||
distBase64 = entityFlow.dist!!,
|
||||
baseBase64 = entityFlow.base!!
|
||||
)
|
||||
@@ -110,6 +170,42 @@ private fun toolViewUiState(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun FlowCollector<ToolViewUiState>.emitResult(
|
||||
result: Result<ToolEntity>,
|
||||
toolViewTemplate: String,
|
||||
globalJsVariables: String,
|
||||
globalCssVariables: String
|
||||
) {
|
||||
emit(
|
||||
when (result) {
|
||||
is Result.Success -> {
|
||||
val dist = result.data.dist!!
|
||||
val base = result.data.base!!
|
||||
ToolViewUiState.Success(
|
||||
result.data.name,
|
||||
processHtml(
|
||||
toolViewTemplate = toolViewTemplate,
|
||||
globalJsVariables = globalJsVariables,
|
||||
globalCssVariables = globalCssVariables,
|
||||
distBase64 = dist,
|
||||
baseBase64 = base
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is Result.Loading -> ToolViewUiState.Loading
|
||||
is Result.Error -> {
|
||||
Timber.e(result.exception, "Can not load tool")
|
||||
ToolViewUiState.Error
|
||||
}
|
||||
|
||||
is Result.Fail -> ToolViewUiState.Error
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
sealed interface ToolViewUiState {
|
||||
data class Success(
|
||||
@@ -122,12 +218,32 @@ sealed interface ToolViewUiState {
|
||||
data object Loading : ToolViewUiState
|
||||
}
|
||||
|
||||
sealed interface WebViewInstanceState {
|
||||
data class Success(
|
||||
val webView: WebView
|
||||
) : WebViewInstanceState
|
||||
|
||||
data object Loading : WebViewInstanceState
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalEncodingApi::class)
|
||||
private fun processHtml(toolViewTemplate: String, distBase64: String, baseBase64: String): String {
|
||||
private fun processHtml(
|
||||
toolViewTemplate: String,
|
||||
globalJsVariables: String,
|
||||
globalCssVariables: String,
|
||||
distBase64: String,
|
||||
baseBase64: String
|
||||
): String {
|
||||
val dist = Base64.decodeToStringWithZip(distBase64)
|
||||
val base = Base64.decodeToStringWithZip(baseBase64)
|
||||
|
||||
return toolViewTemplate.replace("{{replace_code}}", "$dist\n$base")
|
||||
return toolViewTemplate
|
||||
.replace(oldValue = "{{replace_global_js_variables}}", newValue = globalJsVariables)
|
||||
.replace(oldValue = "{{replace_global_css_variables}}", newValue = globalCssVariables)
|
||||
.replace(oldValue = "{{replace_dict_code}}", newValue = dist)
|
||||
.replace(oldValue = "{{replace_base_code}}", newValue = base)
|
||||
}
|
||||
|
||||
data class Quadruple<A, B, C, D>(val first: A, val second: B, val third: C, val fourth: D)
|
||||
|
||||
private const val IS_PREVIEW = "IS_PREVIEW"
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package top.fatweb.oxygen.toolbox.util
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import androidx.activity.compose.ManagedActivityResultLauncher
|
||||
import androidx.annotation.RequiresApi
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import kotlin.let
|
||||
|
||||
fun saveToDownloads(
|
||||
context: Context,
|
||||
permissionLauncher: ManagedActivityResultLauncher<String, Boolean>,
|
||||
data: ByteArray,
|
||||
fileName: String
|
||||
) = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
saveFileToDownloads(context = context, data = data, fileName = fileName)
|
||||
} else {
|
||||
saveFileToDownloads(
|
||||
context = context,
|
||||
permissionLauncher = permissionLauncher,
|
||||
data = data,
|
||||
fileName = fileName
|
||||
)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.Q)
|
||||
private fun saveFileToDownloads(
|
||||
context: Context,
|
||||
data: ByteArray,
|
||||
fileName: String
|
||||
): Boolean {
|
||||
val resolver = context.contentResolver
|
||||
|
||||
val contentValues = ContentValues().apply {
|
||||
put(MediaStore.Downloads.DISPLAY_NAME, fileName)
|
||||
put(MediaStore.Downloads.MIME_TYPE, "application/octet-stream")
|
||||
put(MediaStore.Downloads.IS_PENDING, 1)
|
||||
}
|
||||
|
||||
val collection = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
||||
val fileUri = resolver.insert(collection, contentValues)
|
||||
|
||||
return fileUri?.let { uri ->
|
||||
resolver.openOutputStream(uri)?.use { outputStream ->
|
||||
outputStream.write(data)
|
||||
outputStream.flush()
|
||||
}
|
||||
|
||||
contentValues.clear()
|
||||
contentValues.put(MediaStore.Downloads.IS_PENDING, 0)
|
||||
resolver.update(uri, contentValues, null, null)
|
||||
true
|
||||
} ?: run {
|
||||
Timber.e("Could not save file $fileName to Downloads")
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveFileToDownloads(
|
||||
context: Context,
|
||||
permissionLauncher: ManagedActivityResultLauncher<String, Boolean>,
|
||||
data: ByteArray,
|
||||
fileName: String
|
||||
): Boolean {
|
||||
if (!runBlocking {
|
||||
Permissions.requestWriteExternalStoragePermission(
|
||||
context,
|
||||
permissionLauncher
|
||||
)
|
||||
}) {
|
||||
return false
|
||||
}
|
||||
|
||||
val downloadsDir =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||
val file = File(downloadsDir, fileName)
|
||||
|
||||
return try {
|
||||
FileOutputStream(file).apply {
|
||||
write(data)
|
||||
close()
|
||||
}
|
||||
true
|
||||
} catch (e: IOException) {
|
||||
Timber.e(e, "Could not save file $fileName to ${file.absolutePath}")
|
||||
false
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,13 @@ import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Context.CLIPBOARD_SERVICE
|
||||
import android.util.Base64
|
||||
import android.webkit.JavascriptInterface
|
||||
import android.webkit.WebView
|
||||
import androidx.activity.compose.ManagedActivityResultLauncher
|
||||
|
||||
class NativeWebApi(
|
||||
private val context: Context,
|
||||
private val webView: WebView
|
||||
private val permissionLauncher: ManagedActivityResultLauncher<String, Boolean>
|
||||
) {
|
||||
@JavascriptInterface
|
||||
fun copyToClipboard(text: String): Boolean {
|
||||
@@ -17,7 +18,7 @@ class NativeWebApi(
|
||||
return clipboardManager?.let {
|
||||
it.setPrimaryClip(ClipData.newPlainText("copy", text))
|
||||
true
|
||||
} ?: false
|
||||
} == true
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@@ -26,9 +27,15 @@ class NativeWebApi(
|
||||
return clipboardManager?.primaryClip?.getItemAt(0)?.text?.toString() ?: ""
|
||||
}
|
||||
|
||||
private fun callback(callback: String, vararg args: Any) {
|
||||
val jsCode =
|
||||
"$callback(${args.map { if (it is String) "'$it'" else it }.joinToString(", ")})"
|
||||
webView.evaluateJavascript(jsCode, null)
|
||||
@JavascriptInterface
|
||||
fun saveToDownloads(dataBase64: String, fileName: String): Boolean {
|
||||
val data = Base64.decode(dataBase64, Base64.DEFAULT)
|
||||
|
||||
return saveToDownloads(
|
||||
context = context,
|
||||
permissionLauncher = permissionLauncher,
|
||||
data = data,
|
||||
fileName = fileName
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package top.fatweb.oxygen.toolbox.util
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import androidx.activity.compose.ManagedActivityResultLauncher
|
||||
import androidx.core.content.ContextCompat
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
object Permissions {
|
||||
var continuation: Continuation<Boolean>? = null
|
||||
|
||||
suspend fun requestWriteExternalStoragePermission(
|
||||
context: Context,
|
||||
permissionLauncher: ManagedActivityResultLauncher<String, Boolean>
|
||||
): Boolean {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
return true
|
||||
}
|
||||
|
||||
return suspendCancellableCoroutine { continuation ->
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
context,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
continuation.resume(true)
|
||||
} else {
|
||||
this.continuation = continuation
|
||||
permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
}
|
||||
|
||||
continuation.invokeOnCancellation {
|
||||
continuation.resume(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
@@ -1,194 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
32
app/src/main/res/drawable/ic_launcher.xml
Normal file
@@ -1,170 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
android:fillColor="#4E47BB"
|
||||
android:pathData="M0,0h1024v1024h-1024z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
android:pathData="M307.1,499.6c0,-70.5 86.8,-42.6 58.5,-33.2 -31,10.3 2.1,73.6 11.1,51.3c19.7,-48.9 27,27.9 50.1,27.9c23.1,0 69.4,-119.3 82.4,-88.7c46.9,109.9 66.2,-4.6 86.7,59.3c20.7,64.4 41,-58.9 50.6,-24.7c7.5,26.9 18.8,5.8 28.3,-19.5c10.7,-28.4 41.8,-37.4 41.8,27.5c0,111.5 -88.7,204.7 -204.7,204.7 -116.1,0 -204.7,-93.5 -204.7,-204.7ZM426.7,504c7,0 12.2,6.2 12.2,12.2s-4.9,12.2 -12.2,12.2c-7.3,0 -12.2,-6 -12.2,-12.2c0,-6.2 5.2,-12.2 12.2,-12.2ZM414.5,382.8c5.3,0 9.2,4.7 9.2,9.2s-3.7,9.2 -9.2,9.2 -9.2,-4.5 -9.2,-9.2c0,-4.7 3.9,-9.2 9.2,-9.2ZM377.8,433.6c4.3,0 7.6,3.8 7.6,7.6c0,3.7 -3,7.6 -7.6,7.6 -4.5,0 -7.6,-3.7 -7.6,-7.6c0,-3.8 3.2,-7.6 7.6,-7.6ZM466.2,408.8c11.6,0 20.3,10.3 20.3,20.3s-8.1,20.3 -20.3,20.3 -20.3,-10 -20.3,-20.3s8.7,-20.3 20.3,-20.3ZM614.9,433.6c9.4,0 16.4,8.3 16.4,16.4c0,8.1 -6.6,16.4 -16.4,16.4 -9.8,0 -16.4,-8.1 -16.4,-16.4c0,-8.3 7,-16.4 16.4,-16.4ZM405.9,440c3,0 5.3,2.7 5.3,5.3s-2.1,5.3 -5.3,5.3c-3.2,0 -5.3,-2.6 -5.3,-5.3c0,-2.7 2.3,-5.3 5.3,-5.3ZM528.1,437.2c5.6,0 9.8,5 9.8,9.8c0,4.8 -3.9,9.8 -9.8,9.8s-9.8,-4.9 -9.8,-9.8c0,-5 4.2,-9.8 9.8,-9.8ZM560.5,467.9c8.4,0 14.7,7.5 14.7,14.7s-5.9,14.7 -14.7,14.7 -14.7,-7.3 -14.7,-14.7c0,-7.4 6.3,-14.7 14.7,-14.7ZM459.7,350.8c5.2,0 9,4.6 9,9c0,4.4 -3.6,9 -9,9 -5.4,0 -9,-4.4 -9,-9c0,-4.6 3.8,-9 9,-9ZM352.3,556.4c0,12.9 10.2,25.4 25.4,25.4c15.2,0 25.4,-12.9 25.4,-25.4s-10.9,-25.4 -25.4,-25.4c-14.6,0 -25.4,12.6 -25.4,25.4ZM377.8,535.4c12,0 21,10.7 21,21s-8.4,21 -21,21c-12.6,0 -21,-10.4 -21,-21c0,-10.6 9,-21 21,-21ZM560.1,547.6c0,10.2 8.1,20.1 20.1,20.1s20.1,-10.2 20.1,-20.1 -8.6,-20.1 -20.1,-20.1 -20.1,9.9 -20.1,20.1ZM580.2,532c8.9,0 15.6,7.9 15.6,15.6s-6.3,15.6 -15.6,15.6 -15.6,-7.7 -15.6,-15.6c0,-7.9 6.7,-15.6 15.6,-15.6ZM403.2,615.3c0,4.5 3.6,8.9 8.9,8.9s8.9,-4.5 8.9,-8.9 -3.8,-8.9 -8.9,-8.9c-5.1,0 -8.9,4.4 -8.9,8.9ZM412.2,609.1c3.6,0 6.2,3.2 6.2,6.2s-2.5,6.2 -6.2,6.2c-3.7,0 -6.2,-3.1 -6.2,-6.2s2.7,-6.2 6.2,-6.2ZM441,566.5c0,3 2.4,5.9 5.9,5.9s5.9,-3 5.9,-5.9c0,-2.9 -2.5,-5.9 -5.9,-5.9 -3.4,0 -5.9,2.9 -5.9,5.9ZM446.9,562.4c2.4,0 4.1,2.1 4.1,4.1c0,2 -1.7,4.1 -4.1,4.1s-4.1,-2 -4.1,-4.1c0,-2.1 1.8,-4.1 4.1,-4.1ZM587.6,592.6c0,3 2.4,5.9 5.9,5.9s5.9,-3 5.9,-5.9 -2.5,-5.9 -5.9,-5.9 -5.9,2.9 -5.9,5.9ZM593.5,588.5c2.4,0 4.1,2.1 4.1,4.1c0,2 -1.7,4.1 -4.1,4.1s-4.1,-2 -4.1,-4.1c0,-2.1 1.8,-4.1 4.1,-4.1ZM634.6,592.6c0,3 2.4,5.9 5.9,5.9s5.9,-3 5.9,-5.9 -2.5,-5.9 -5.9,-5.9c-3.4,0 -5.9,2.9 -5.9,5.9ZM640.5,588.5c2.4,0 4.1,2.1 4.1,4.1c0,2 -1.7,4.1 -4.1,4.1s-4.1,-2 -4.1,-4.1c0,-2.1 1.8,-4.1 4.1,-4.1ZM566.1,582.8c0,3 2.4,5.9 5.9,5.9s5.9,-3 5.9,-5.9c0,-2.9 -2.5,-5.9 -5.9,-5.9s-5.9,2.9 -5.9,5.9ZM572,578.7c2.4,0 4.1,2.1 4.1,4.1c0,2 -1.7,4.1 -4.1,4.1s-4.1,-2 -4.1,-4.1c0,-2.1 1.8,-4.1 4.1,-4.1ZM480.7,624.3c0,3 2.4,5.9 5.9,5.9s5.9,-3 5.9,-5.9c0,-2.9 -2.5,-5.9 -5.9,-5.9s-5.9,2.9 -5.9,5.9ZM486.6,620.1c2.4,0 4.1,2.1 4.1,4.1c0,2 -1.7,4.1 -4.1,4.1s-4.1,-2 -4.1,-4.1c0,-2.1 1.8,-4.1 4.1,-4.1ZM652.3,553.7c0,6.5 5.2,12.9 12.9,12.9s12.9,-6.5 12.9,-12.9 -5.5,-12.9 -12.9,-12.9c-7.4,0 -12.9,6.4 -12.9,12.9ZM665.2,544.1c5.5,0 9.5,4.8 9.5,9.5s-3.8,9.5 -9.5,9.5 -9.5,-4.7 -9.5,-9.5s4.1,-9.5 9.5,-9.5ZM492.4,495.5c0,6.5 5.2,12.9 12.9,12.9c7.7,0 12.9,-6.5 12.9,-12.9s-5.5,-12.9 -12.9,-12.9c-7.4,0 -12.9,6.4 -12.9,12.9ZM505.3,485.9c5.5,0 9.5,4.8 9.5,9.5s-3.8,9.5 -9.5,9.5 -9.5,-4.7 -9.5,-9.5s4.1,-9.5 9.5,-9.5ZM492.5,588.8c0,5 3.9,9.8 9.8,9.8s9.8,-5 9.8,-9.8c0,-4.8 -4.2,-9.8 -9.8,-9.8s-9.8,4.9 -9.8,9.8ZM502.3,581.9c3.9,0 6.9,3.5 6.9,6.9c0,3.4 -2.8,6.9 -6.9,6.9s-6.9,-3.4 -6.9,-6.9c0,-3.5 2.9,-6.9 6.9,-6.9ZM600.5,625.1c0,5 3.9,9.8 9.8,9.8s9.8,-5 9.8,-9.8c0,-4.8 -4.2,-9.8 -9.8,-9.8s-9.8,4.9 -9.8,9.8ZM610.4,618.3c3.9,0 6.9,3.5 6.9,6.9c0,3.4 -2.7,6.9 -6.9,6.9s-6.9,-3.4 -6.9,-6.9c0,-3.5 2.9,-6.9 6.9,-6.9ZM518.3,527.5c0,5 3.9,9.8 9.8,9.8s9.8,-5 9.8,-9.8 -4.2,-9.8 -9.8,-9.8 -9.8,4.9 -9.8,9.8ZM528.1,520.6c3.9,0 6.9,3.5 6.9,6.9s-2.7,6.9 -6.9,6.9 -6.9,-3.4 -6.9,-6.9s2.9,-6.9 6.9,-6.9ZM466.2,531c0,5 3.9,9.8 9.8,9.8s9.8,-5 9.8,-9.8 -4.2,-9.8 -9.8,-9.8 -9.8,4.9 -9.8,9.8ZM476,524.1c3.9,0 6.9,3.5 6.9,6.9s-2.8,6.9 -6.9,6.9c-4.1,0 -6.9,-3.4 -6.9,-6.9s2.9,-6.9 6.9,-6.9ZM550.4,318.3c27.5,0 45.7,20.8 45.7,45.7c0,24.9 -19.8,45.7 -45.7,45.7s-45.7,-20.8 -45.7,-45.7c0,-24.9 18.2,-45.7 45.7,-45.7ZM550.4,318.3"
|
||||
tools:ignore="VectorPath" />
|
||||
</vector>
|
||||
@@ -1,176 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_background.png
Normal file
|
After Width: | Height: | Size: 857 B |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_background.png
Normal file
|
After Width: | Height: | Size: 463 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_background.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
@@ -4,6 +4,8 @@
|
||||
<string name="app_full_name">氧工具</string>
|
||||
<string name="app_description">All in One</string>
|
||||
|
||||
<string name="core_beta_version">测试版</string>
|
||||
<string name="core_ga_version">正式版</string>
|
||||
<string name="core_ok">完成</string>
|
||||
<string name="core_back">返回</string>
|
||||
<string name="core_close">关闭</string>
|
||||
@@ -12,6 +14,8 @@
|
||||
<string name="core_search">搜索</string>
|
||||
<string name="core_loading">加载中…</string>
|
||||
<string name="core_no_connect">⚠️ 无法连接至互联网</string>
|
||||
<string name="core_full_screen">全屏</string>
|
||||
<string name="core_exit_full_screen">退出全屏</string>
|
||||
<string name="core_install">安装</string>
|
||||
<string name="core_installing">安装中……</string>
|
||||
<string name="core_upgrade">更新</string>
|
||||
@@ -24,6 +28,11 @@
|
||||
<string name="core_undo">撤消</string>
|
||||
<string name="core_nothing">空空如也</string>
|
||||
<string name="core_nothing_found">未找到相关内容</string>
|
||||
<string name="core_file_select_one">选择一个文件</string>
|
||||
<string name="core_file_select_multi">选择文件</string>
|
||||
<string name="core_file_select_one_text">选择一个文本文件</string>
|
||||
<string name="core_file_select_multi_text">选择文本文件</string>
|
||||
<string name="core_can_only_download_http_https">只能下载 HTTP/HTTPS URI:%1$s</string>
|
||||
|
||||
<string name="feature_store_title">商店</string>
|
||||
<string name="feature_store_retry">重试</string>
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
<string name="app_full_name">Oxygen Toolbox</string>
|
||||
<string name="app_description">All in One</string>
|
||||
|
||||
<string name="core_beta_version">Beta</string>
|
||||
<string name="core_ga_version">GA</string>
|
||||
<string name="core_ok">OK</string>
|
||||
<string name="core_back">Back</string>
|
||||
<string name="core_close">Close</string>
|
||||
@@ -11,6 +13,8 @@
|
||||
<string name="core_search">Search</string>
|
||||
<string name="core_loading">Loading…</string>
|
||||
<string name="core_no_connect">⚠️ Unable to connect to the internet</string>
|
||||
<string name="core_full_screen">Full Screen</string>
|
||||
<string name="core_exit_full_screen">Exit Full Screen</string>
|
||||
<string name="core_install">Install</string>
|
||||
<string name="core_installing">Installing…</string>
|
||||
<string name="core_upgrade">Upgrade</string>
|
||||
@@ -23,6 +27,11 @@
|
||||
<string name="core_undo">Undo</string>
|
||||
<string name="core_nothing">Nothing</string>
|
||||
<string name="core_nothing_found">Nothing found</string>
|
||||
<string name="core_file_select_one">Select a file</string>
|
||||
<string name="core_file_select_multi">Select files</string>
|
||||
<string name="core_file_select_one_text">Select a text file</string>
|
||||
<string name="core_file_select_multi_text">Select text files</string>
|
||||
<string name="core_can_only_download_http_https">Can only download HTTP/HTTPS URIs: %1$s</string>
|
||||
|
||||
<string name="feature_store_title">Store</string>
|
||||
<string name="feature_store_retry">try again</string>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</style>
|
||||
|
||||
<style name="Theme.Oxygen.Splash" parent="NightAdjusted.Theme.Splash">
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_oxygen</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_launcher</item>
|
||||
<item name="postSplashScreenTheme">@style/Theme.Oxygen</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -1,31 +1,32 @@
|
||||
[versions]
|
||||
agp = "8.5.2"
|
||||
kotlin = "2.0.10"
|
||||
ksp = "2.0.10-1.0.24"
|
||||
aboutlibraries = "11.2.2"
|
||||
agp = "8.7.2"
|
||||
kotlin = "2.0.20"
|
||||
ksp = "2.0.20-1.0.25"
|
||||
aboutlibraries = "11.2.3"
|
||||
protobufPlugin = "0.9.4"
|
||||
kotlinxSerialization = "2.0.0"
|
||||
kotlinxSerialization = "2.0.20"
|
||||
secrets = "2.0.1"
|
||||
paging = "3.3.2"
|
||||
|
||||
desugarJdkLibs = "2.1.0"
|
||||
composeBom = "2024.08.00"
|
||||
desugarJdkLibs = "2.1.2"
|
||||
composeBom = "2024.10.01"
|
||||
junit = "4.13.2"
|
||||
coreKtx = "1.13.1"
|
||||
coreKtx = "1.15.0"
|
||||
junitVersion = "1.2.1"
|
||||
espressoCore = "3.6.1"
|
||||
activityCompose = "1.9.1"
|
||||
uiTestManifest = "1.7.5"
|
||||
activityCompose = "1.9.3"
|
||||
appcompat = "1.7.0"
|
||||
androidxLifecycle = "2.8.4"
|
||||
androidxLifecycle = "2.8.7"
|
||||
androidxCoreSplashscreen = "1.0.1"
|
||||
hilt = "2.52"
|
||||
coil = "2.7.0"
|
||||
kotlinxDatetime = "0.6.0"
|
||||
kotlinxDatetime = "0.6.1"
|
||||
androidxDataStore = "1.1.1"
|
||||
protobuf = "4.27.3"
|
||||
androidxNavigation = "2.7.7"
|
||||
protobuf = "4.28.3"
|
||||
androidxNavigation = "2.8.3"
|
||||
androidxHiltNavigationCompose = "1.2.0"
|
||||
kotlinxSerializationJson = "1.7.1"
|
||||
kotlinxSerializationJson = "1.7.3"
|
||||
retrofit = "2.11.0"
|
||||
retrofitKotlinxSerializationJson = "1.0.0"
|
||||
okhttp = "4.12.0"
|
||||
@@ -59,7 +60,7 @@ androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "j
|
||||
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||
|
||||
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
|
||||
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
||||
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest", version.ref = "uiTestManifest" }
|
||||
|
||||
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
|
||||
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
|
||||
@@ -69,6 +70,7 @@ androidx-material3 = { group = "androidx.compose.material3", name = "material3"
|
||||
material-icons-core = { group = "androidx.compose.material", name = "material-icons-core" }
|
||||
material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" }
|
||||
material3-window-size = { group = "androidx.compose.material3", name = "material3-window-size-class" }
|
||||
animation-graphics = { group = "androidx.compose.animation", name = "animation-graphics" }
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
|
||||
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
||||
|
||||