Feat(All): Tis
some changes
@@ -10,6 +10,18 @@
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
<SelectionState runConfigName="practice.PSP.tis">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
<SelectionState runConfigName="tis_app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
<SelectionState runConfigName="stage_app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
||||
@@ -12,9 +12,10 @@
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/core" />
|
||||
<option value="$PROJECT_DIR$/design_system" />
|
||||
<option value="$PROJECT_DIR$/ps3" />
|
||||
<option value="$PROJECT_DIR$/p3" />
|
||||
<option value="$PROJECT_DIR$/ps4" />
|
||||
<option value="$PROJECT_DIR$/tis_sep" />
|
||||
<option value="$PROJECT_DIR$/stage_app" />
|
||||
<option value="$PROJECT_DIR$/tis_app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PlanningModeManager">
|
||||
<option name="approvalStates">
|
||||
<map>
|
||||
<entry key="20260504-162003-d0f92a5d-1a15-429a-82cc-cad6ed3c0e3e" value="true" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.example.core.data
|
||||
|
||||
import com.example.core.domain.AppConfig
|
||||
|
||||
class AppConfigImpl : AppConfig{
|
||||
override fun androidId(id: String): String {
|
||||
return "window.WebV.onUUID($id);"
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ class PaymentResultImpl @Inject constructor(
|
||||
) : PaymentResult {
|
||||
|
||||
override fun post(paymentResultEntity: PaymentResultEntity?): String {
|
||||
return "window.onPaymentResult(${gson.toJson(paymentResultEntity)});"
|
||||
return "window.WebV.onPaymentResult(${gson.toJson(paymentResultEntity)});"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.example.core.di
|
||||
|
||||
import com.example.core.data.AppConfigImpl
|
||||
import com.example.core.data.PaymentResultImpl
|
||||
import com.example.core.domain.AppConfig
|
||||
import com.example.core.domain.PaymentResult
|
||||
import com.google.gson.Gson
|
||||
import dagger.Module
|
||||
@@ -23,4 +25,9 @@ class CoreModule {
|
||||
): PaymentResult = PaymentResultImpl(
|
||||
gson = gson
|
||||
)
|
||||
|
||||
@Provides
|
||||
fun provideAppConfig(
|
||||
gson: Gson
|
||||
): AppConfig = AppConfigImpl()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.example.core.domain
|
||||
|
||||
import com.example.core.model.PaymentResultEntity
|
||||
|
||||
interface AppConfig {
|
||||
fun androidId(id : String) : String
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.example.core.domain
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.example.core.model.PrintEntity
|
||||
|
||||
interface Printer {
|
||||
|
||||
fun print(
|
||||
printEntities: List<PrintEntity>,
|
||||
@DrawableRes icon :Int)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.example.core.model
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
@Keep
|
||||
data class PrintEntity(
|
||||
val title: String? = null,
|
||||
val items: List<ItemEntity>? = null,
|
||||
val paragraph: String? = null,
|
||||
val type: Type
|
||||
|
||||
) {
|
||||
data class ItemEntity(
|
||||
val label: String,
|
||||
val value: String,
|
||||
)
|
||||
|
||||
enum class Type() {
|
||||
CARD,
|
||||
PARAGRAPH
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<!--
|
||||
~ Copyright (C) 2026 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="800dp"
|
||||
android:height="200dp"
|
||||
android:viewportWidth="800"
|
||||
android:viewportHeight="200">
|
||||
<path
|
||||
android:pathData="M1.2,101.4L6.2,101.4L27.2,101.4L53.2,101.4L69.2,101.4L87.2,101.4L103.2,101.4L117.2,101.4L126.2,101.4L134.2,101.4L144.2,101.4L150.2,101.4L162.2,101.4L179.2,101.4L197.2,101.4L217.2,101.4L231.2,101.4L252.2,101.4L265.2,101.4L282.2,101.4L293.2,101.4L313.2,101.4L336.2,101.4L357.2,101.4L377.2,101.4L400.2,101.4L433.2,101.4L456.2,101.4L489.2,101.4L515.2,101.4L515.2,101.4L521.2,101.4L545.2,101.4L581.2,101.4L605.2,101.4L633.2,101.4L649.2,101.4L663.2,101.4L672.2,101.4L684.2,101.4L691.2,101.4L701.2,101.4L713.2,101.4L722.2,101.4L737.2,101.4L747.2,101.4L752.2,101.4L761.2,101.4L769.2,101.4L781.2,101.4L787.2,101.4L794.2,101.4L797.2,101.4L799.2,101.4L801.2,101.4"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="8"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
~ Copyright (C) 2026 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="256dp"
|
||||
android:height="2dp"
|
||||
android:viewportWidth="24.8"
|
||||
android:viewportHeight="8">
|
||||
<path
|
||||
android:pathData="M0,0h24.8v248h-24.8z"
|
||||
android:strokeWidth="0"
|
||||
android:fillColor="#000000"
|
||||
android:strokeColor="#000000"/>
|
||||
</vector>
|
||||
@@ -37,6 +37,7 @@ dependencies {
|
||||
implementation(libs.androidx.compose.ui.tooling.preview)
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||
implementation(libs.retrofit.converter.gson)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
|
||||
@@ -44,4 +45,6 @@ dependencies {
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
debugImplementation(libs.androidx.compose.ui.test.manifest)
|
||||
debugImplementation(libs.androidx.compose.ui.tooling)
|
||||
|
||||
implementation(project(":core"))
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.example.design_system
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.JavascriptInterface
|
||||
import android.webkit.WebResourceError
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebSettings
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
@@ -15,14 +17,17 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import com.example.core.model.PrintEntity
|
||||
import com.example.design_system.util.PspJavaScriptInterface
|
||||
import com.example.design_system.util.snackbar.SnackbarController
|
||||
import com.example.design_system.util.snackbar.SnackbarEvent
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@SuppressLint("JavascriptInterface")
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun PspWebView(
|
||||
@@ -31,7 +36,8 @@ fun PspWebView(
|
||||
modifier: Modifier = Modifier,
|
||||
onWebView: (WebView) -> Unit,
|
||||
onPayClick: (amount: Long, id: String?) -> Unit,
|
||||
onPrintClick: () -> Unit,
|
||||
onUUID: () -> Unit,
|
||||
onPrintClick: (printEntities: List<PrintEntity>) -> Unit,
|
||||
) {
|
||||
|
||||
val canGoBack = remember { mutableStateOf(false) }
|
||||
@@ -40,6 +46,18 @@ fun PspWebView(
|
||||
var lastBackTime by remember { mutableLongStateOf(0L) }
|
||||
var isPaymentLaunching by remember { mutableStateOf(false) }
|
||||
|
||||
// Use rememberUpdatedState to ensure the bridge always calls the latest callbacks
|
||||
val currentOnPayClick by rememberUpdatedState(onPayClick)
|
||||
val currentOnPrintClick by rememberUpdatedState(onPrintClick)
|
||||
val currentOnUUID by rememberUpdatedState(onUUID)
|
||||
|
||||
val bridge = remember {
|
||||
PspJavaScriptInterface(
|
||||
onPayClick = { amount, id -> currentOnPayClick(amount, id) },
|
||||
onPrintClick = { entities -> currentOnPrintClick(entities) },
|
||||
onUUID = { currentOnUUID() }
|
||||
)
|
||||
}
|
||||
|
||||
BackHandler {
|
||||
if (canGoBack.value) {
|
||||
@@ -61,7 +79,6 @@ fun PspWebView(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AndroidView(
|
||||
modifier = modifier,
|
||||
factory = { ctx ->
|
||||
@@ -89,23 +106,7 @@ fun PspWebView(
|
||||
"Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 Chrome/120.0 Mobile Safari/537.36"
|
||||
}
|
||||
|
||||
addJavascriptInterface(
|
||||
|
||||
object : PspJavaScriptInterface {
|
||||
|
||||
|
||||
@JavascriptInterface
|
||||
override fun pay(amount: Long, id: String?) {
|
||||
onPayClick(amount, id)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
override fun print(text: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
}, "AndroidPSP"
|
||||
)
|
||||
addJavascriptInterface(bridge, "NativeBridge")
|
||||
|
||||
|
||||
loadUrl(url)
|
||||
|
||||
@@ -1,8 +1,51 @@
|
||||
package com.example.design_system.util
|
||||
|
||||
interface PspJavaScriptInterface {
|
||||
import android.util.Log
|
||||
import android.webkit.JavascriptInterface
|
||||
import androidx.annotation.Keep
|
||||
import com.example.core.model.PrintEntity
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
|
||||
fun pay(amount: Long,id: String?)
|
||||
@Keep
|
||||
class PspJavaScriptInterface(
|
||||
private val onPayClick: (Long, String?) -> Unit,
|
||||
private val onPrintClick: (List<PrintEntity>) -> Unit,
|
||||
private val onUUID: () -> Unit,
|
||||
) {
|
||||
|
||||
fun print(text: String)
|
||||
}
|
||||
@JavascriptInterface
|
||||
@Keep
|
||||
fun pay(amount: Double, id: String?) {
|
||||
Log.d("PspBridge", "pay called: amount=$amount, id=$id")
|
||||
try {
|
||||
onPayClick(amount.toLong(), id)
|
||||
} catch (e: Exception) {
|
||||
Log.e("PspBridge", "Error in pay callback", e)
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@Keep
|
||||
fun print(printEntitiesJson: String) {
|
||||
Log.d("PspBridge", "print called: $printEntitiesJson")
|
||||
try {
|
||||
val type = object : TypeToken<List<PrintEntity>>() {}.type
|
||||
val list: List<PrintEntity> = Gson().fromJson(printEntitiesJson, type)
|
||||
onPrintClick(list)
|
||||
} catch (e: Exception) {
|
||||
Log.e("PspBridge", "Error parsing print entities", e)
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@Keep
|
||||
fun uuid() {
|
||||
Log.d("PspBridge", "uuid called")
|
||||
try {
|
||||
onUUID()
|
||||
} catch (e: Exception) {
|
||||
Log.e("PspBridge", "Error in uuid callback", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,24 +5,29 @@ plugins {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.example.ps3"
|
||||
compileSdk {
|
||||
version = release(36) {
|
||||
minorApiLevel = 1
|
||||
}
|
||||
}
|
||||
namespace = "com.example.p3"
|
||||
compileSdk = 36
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 24
|
||||
|
||||
// targetSdk is often not needed for library modules
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles("consumer-rules.pro")
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -39,10 +44,7 @@ dependencies {
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
|
||||
// implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
|
||||
|
||||
|
||||
// 2. This specifically includes the platform SDK jar
|
||||
compileOnly(files("libs/platform_sdk_v2.3.706.jar"))
|
||||
|
||||
// Using implementation to bundle the JAR and avoid NoClassDefFoundError
|
||||
implementation(files("libs/platform_sdk_v2.3.706.jar"))
|
||||
implementation(files("libs/classes-2.1.17.jar"))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.ps3
|
||||
package com.example.p3
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.ps3
|
||||
package com.example.p3
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -6,7 +6,7 @@ import android.content.pm.PackageManager
|
||||
import androidx.activity.result.ActivityResult
|
||||
import com.example.core.model.PaymentResultEntity
|
||||
import com.example.core.model.PaymentResultStatus
|
||||
import com.example.ps3.models.IapAccountSplit
|
||||
import com.example.p3.models.IapAccountSplit
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import javax.inject.Inject
|
||||
@@ -0,0 +1,333 @@
|
||||
package com.example.p3
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.util.Log
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.createBitmap
|
||||
import com.example.core.domain.Printer
|
||||
import com.example.core.model.PrintEntity
|
||||
import com.pos.sdk.printer.POIPrinterManager
|
||||
import com.pos.sdk.printer.POIPrinterManager.IPrinterListener
|
||||
import com.pos.sdk.printer.models.BitmapPrintLine
|
||||
import com.pos.sdk.printer.models.PrintLine
|
||||
import com.pos.sdk.printer.models.TextPrintLine
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class P3Printer @Inject constructor(
|
||||
@param:ApplicationContext private val context: Context,
|
||||
) : Printer {
|
||||
companion object {
|
||||
private const val TAG = "Printer"
|
||||
|
||||
// Printer state constants (should ideally come from the SDK if available)
|
||||
private const val PRINTER_STATE_ERROR = 4
|
||||
private const val DEFAULT_PRINT_GRAY = 2000
|
||||
private const val DEFAULT_LINE_SPACE = 5
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a sample receipt for demonstration.
|
||||
*/
|
||||
fun printSampleReceipt(context: Context) {
|
||||
// Use applicationContext to avoid potential memory leaks
|
||||
|
||||
val printerManager = initialP3Printer()
|
||||
|
||||
printerManager?.apply {
|
||||
setPrintGray(DEFAULT_PRINT_GRAY)
|
||||
setLineSpace(DEFAULT_LINE_SPACE)
|
||||
|
||||
// Header
|
||||
addPrintLine(TextPrintLine("This is an example of a receipt", PrintLine.CENTER))
|
||||
|
||||
// Reusable logo bitmap
|
||||
val logoBitmap = drawableToBitmap(context, android.R.drawable.btn_plus)
|
||||
val logoLine = logoBitmap?.let { BitmapPrintLine(it, PrintLine.CENTER) }
|
||||
|
||||
logoLine?.let { addPrintLine(it) }
|
||||
|
||||
// Address
|
||||
val addressFont = getFontPath("font")
|
||||
if (addressFont.isNotEmpty()) {
|
||||
setPrintFont(addressFont)
|
||||
} else {
|
||||
setPrintFont("/system/fonts/ComingSoon.ttf")
|
||||
}
|
||||
addPrintLine(
|
||||
TextPrintLine(
|
||||
"Floor ** , Building **, No.*** LONG DONG Avenue, Pudong New District, Shanghai, China",
|
||||
PrintLine.LEFT,
|
||||
20
|
||||
)
|
||||
)
|
||||
|
||||
// Transaction Details
|
||||
val detailFont = getFontPath("font")
|
||||
if (detailFont.isNotEmpty()) {
|
||||
setPrintFont(detailFont)
|
||||
} else {
|
||||
setPrintFont("/system/fonts/DroidSansMono.ttf")
|
||||
}
|
||||
// addPrintLine(createPrintRow("24 June 2025", " Assistant 6", "815002", size = 18))
|
||||
// addPrintLine(createPrintRow("Item", "Quantity", "Price", size = 24, isBold = true))
|
||||
// addPrintLine(createPrintRow("Tomato", "1", "$2.08", size = 24))
|
||||
// addPrintLine(createPrintRow("Orange", "1", "$1.06", size = 24))
|
||||
//
|
||||
// Footer
|
||||
addPrintLine(TextPrintLine("Total $3.14", PrintLine.RIGHT))
|
||||
addPrintLine(TextPrintLine(""))
|
||||
logoLine?.let { addPrintLine(it) }
|
||||
addPrintLine(TextPrintLine(""))
|
||||
|
||||
addPrintLine(
|
||||
TextPrintLine(
|
||||
"Did you know you could have earned Rewards points on this purchase?",
|
||||
PrintLine.CENTER
|
||||
)
|
||||
)
|
||||
addPrintLine(
|
||||
TextPrintLine(
|
||||
"Simply sign up today for a Membership Card!",
|
||||
PrintLine.CENTER
|
||||
)
|
||||
)
|
||||
|
||||
logoLine?.let { addPrintLine(it) }
|
||||
addPrintLine(TextPrintLine(" ", 0, 100))
|
||||
|
||||
val listener = object : IPrinterListener {
|
||||
override fun onStart() {
|
||||
Log.d(TAG, "Print started")
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
Log.d(TAG, "Print finished")
|
||||
close()
|
||||
}
|
||||
|
||||
override fun onError(code: Int, msg: String?) {
|
||||
Log.e(TAG, "Print error - code: $code, message: $msg")
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
beginPrint(listener)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initialP3Printer(): POIPrinterManager? {
|
||||
val printerManager = POIPrinterManager(context.applicationContext)
|
||||
printerManager.open()
|
||||
|
||||
val state = printerManager.printerState
|
||||
Log.d(TAG, "Printer state = $state")
|
||||
|
||||
if (state == PRINTER_STATE_ERROR) {
|
||||
Log.e(TAG, "Printer is in an error state ($state). Aborting print.")
|
||||
printerManager.close()
|
||||
return null
|
||||
}
|
||||
|
||||
return printerManager
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a row with left, center, and right aligned text.
|
||||
*/
|
||||
private fun createPrintRow(
|
||||
label: String,
|
||||
value: String,
|
||||
size: Int,
|
||||
isBold: Boolean = false
|
||||
): List<TextPrintLine> {
|
||||
return if (value.hasPersianLetters()) {
|
||||
|
||||
listOf(
|
||||
TextPrintLine(label, PrintLine.LEFT, size, true),
|
||||
TextPrintLine(value, PrintLine.RIGHT, size, isBold)
|
||||
)
|
||||
} else {
|
||||
|
||||
listOf(
|
||||
TextPrintLine(label, PrintLine.LEFT, size, true),
|
||||
TextPrintLine(value, PrintLine.LEFT, size, isBold)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFontPath(resourceName: String): String {
|
||||
return try {
|
||||
// Find resource ID by name (e.g., "font") in the "font" resource folder
|
||||
val resId = context.resources.getIdentifier(resourceName, "font", context.packageName)
|
||||
if (resId == 0) {
|
||||
Log.e(TAG, "Font resource not found: $resourceName")
|
||||
return ""
|
||||
}
|
||||
|
||||
val fileName = "$resourceName.ttf"
|
||||
val fontFile = File(context.filesDir, fileName)
|
||||
if (!fontFile.exists()) {
|
||||
context.resources.openRawResource(resId).use { input ->
|
||||
fontFile.outputStream().use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
fontFile.absolutePath
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error loading font from resources: $resourceName", e)
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
override fun print(
|
||||
printEntities: List<PrintEntity>,
|
||||
@DrawableRes icon: Int
|
||||
) {
|
||||
val printerManager = initialP3Printer()
|
||||
|
||||
printerManager?.apply {
|
||||
setPrintGray(DEFAULT_PRINT_GRAY)
|
||||
setLineSpace(DEFAULT_LINE_SPACE)
|
||||
|
||||
// Reusable logo bitmap
|
||||
val logoBitmap = drawableToBitmap(context, icon, 200)
|
||||
if (logoBitmap != null) {
|
||||
val logoLine = BitmapPrintLine(logoBitmap, PrintLine.CENTER)
|
||||
addPrintLine(logoLine)
|
||||
addPrintLine(TextPrintLine(" ", 0, 10))
|
||||
}
|
||||
|
||||
val customFontPath = getFontPath("font")
|
||||
if (customFontPath.isNotEmpty()) {
|
||||
setPrintFont(customFontPath)
|
||||
} else {
|
||||
setPrintFont("/system/fonts/DroidSansMono.ttf") // Fallback
|
||||
}
|
||||
|
||||
val divider = drawableToBitmap(context, com.example.core.R.drawable.horizontal_line_svgrepo_com__1_)
|
||||
|
||||
printEntities.forEachIndexed { index, printEntity ->
|
||||
|
||||
// Header
|
||||
printEntity.title?.let {title->
|
||||
addPrintLine(
|
||||
TextPrintLine(
|
||||
title,
|
||||
if (title.hasPersianLetters()) PrintLine.LEFT else PrintLine.RIGHT
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
printEntity.items?.let {items->
|
||||
items.forEach { itemEntity ->
|
||||
addPrintLine(
|
||||
createPrintRow(
|
||||
label = itemEntity.label,
|
||||
value = itemEntity.value,
|
||||
size = 16,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
if (divider != null && printEntities.lastIndex > index) {
|
||||
val dividerLine = BitmapPrintLine(divider, PrintLine.CENTER)
|
||||
addPrintLine(dividerLine)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
addPrintLine(TextPrintLine(" ", 0, 60))
|
||||
|
||||
val listener = object : IPrinterListener {
|
||||
override fun onStart() {
|
||||
Log.d(TAG, "Print started")
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
Log.d(TAG, "Print finished")
|
||||
close()
|
||||
}
|
||||
|
||||
override fun onError(code: Int, msg: String?) {
|
||||
Log.e(TAG, "Print error - code: $code, message: $msg")
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
beginPrint(listener)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// private fun fixForPrinter(input: String): String {
|
||||
// val LRM = '\u200E' // کنترل جهت
|
||||
//
|
||||
// return input
|
||||
// .toPersianDigits() // همونی که قبل دادم
|
||||
// .replace(Regex("(\\d+)")) { matchResult ->
|
||||
// "$LRM${matchResult.value}$LRM"
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun String.hasPersianLetters(): Boolean {
|
||||
return Regex("[\\u0621-\\u0628\\u062A-\\u063A\\u0641-\\u0642\\u0644-\\u0648\\u067E\\u0686\\u0698\\u06A9\\u06AF\\u06CC\\u0647]").containsMatchIn(
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
private fun drawableToBitmap(context: Context, @DrawableRes drawableId: Int): Bitmap? {
|
||||
val drawable = ContextCompat.getDrawable(context, drawableId) ?: return null
|
||||
|
||||
if (drawable is BitmapDrawable) {
|
||||
return drawable.bitmap
|
||||
}
|
||||
|
||||
val bitmap = createBitmap(
|
||||
drawable.intrinsicWidth.coerceAtLeast(1),
|
||||
drawable.intrinsicHeight.coerceAtLeast(1)
|
||||
)
|
||||
val canvas = Canvas(bitmap)
|
||||
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
||||
drawable.draw(canvas)
|
||||
|
||||
return bitmap
|
||||
}
|
||||
|
||||
private fun drawableToBitmap(
|
||||
context: Context,
|
||||
@DrawableRes drawableId: Int,
|
||||
maxWidth: Int = 300
|
||||
): Bitmap? {
|
||||
val drawable = ContextCompat.getDrawable(context, drawableId) ?: return null
|
||||
|
||||
val original = if (drawable is BitmapDrawable) {
|
||||
drawable.bitmap
|
||||
} else {
|
||||
val bitmap = createBitmap(
|
||||
drawable.intrinsicWidth.coerceAtLeast(1),
|
||||
drawable.intrinsicHeight.coerceAtLeast(1)
|
||||
)
|
||||
val canvas = Canvas(bitmap)
|
||||
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
||||
drawable.draw(canvas)
|
||||
bitmap
|
||||
}
|
||||
|
||||
// 👇 scale با حفظ نسبت
|
||||
val ratio = maxWidth.toFloat() / original.width
|
||||
val width = maxWidth
|
||||
val height = (original.height * ratio).toInt()
|
||||
|
||||
return Bitmap.createScaledBitmap(original, width, height, true)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.ps3
|
||||
package com.example.p3
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.activity.result.ActivityResult
|
||||
@@ -8,7 +8,7 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import javax.inject.Inject
|
||||
|
||||
class Ps3Service @Inject constructor(
|
||||
class P3Service @Inject constructor(
|
||||
private val iapPosService: IapPosService,
|
||||
private val printerHelper: PrinterHelper
|
||||
) : PspService {
|
||||
@@ -21,9 +21,8 @@ class Ps3Service @Inject constructor(
|
||||
}
|
||||
|
||||
override fun print(lines: List<String>, onMessage: (String) -> Unit) {
|
||||
// printerHelper.printText()
|
||||
printerHelper.printLines(lines) { status ->
|
||||
onMessage("PS3 Printer: $status")
|
||||
onMessage("P3 Printer: $status")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.ps3
|
||||
package com.example.p3
|
||||
|
||||
import android.device.PrinterManager
|
||||
import android.graphics.Bitmap
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.example.ps3.di
|
||||
package com.example.p3.di
|
||||
|
||||
import android.content.Context
|
||||
import com.example.ps3.IapPosService
|
||||
import com.example.p3.IapPosService
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
@@ -11,7 +11,7 @@ import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object Ps3Module {
|
||||
object P3Module {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.ps3.models
|
||||
package com.example.p3.models
|
||||
|
||||
data class IapAccountSplit(
|
||||
val index: Int,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.ps3
|
||||
package com.example.p3
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.example.ps4
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.example.core.domain.Printer
|
||||
import com.example.core.model.PrintEntity
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class P4Printer @Inject constructor(
|
||||
private val context: Context,
|
||||
) : Printer {
|
||||
|
||||
|
||||
override fun print(
|
||||
printEntities: List<PrintEntity>,
|
||||
@DrawableRes icon: Int
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,9 @@ dependencyResolutionManagement {
|
||||
|
||||
rootProject.name = "PSP"
|
||||
include(":app")
|
||||
include(":tis_sep")
|
||||
include(":ps3")
|
||||
include(":tis_app")
|
||||
include(":p3")
|
||||
include(":ps4")
|
||||
include(":core")
|
||||
include(":design_system")
|
||||
include(":stage_app")
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
alias(libs.plugins.ksp)
|
||||
alias(libs.plugins.hilt)}
|
||||
|
||||
android {
|
||||
namespace = "com.example.stage_app"
|
||||
compileSdk {
|
||||
version = release(36) {
|
||||
minorApiLevel = 1
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.example.stage_app"
|
||||
minSdk = 24
|
||||
targetSdk = 36
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
flavorDimensions.add("module")
|
||||
productFlavors {
|
||||
create("p3") {
|
||||
dimension = "module"
|
||||
}
|
||||
create("ps4") {
|
||||
dimension = "module"
|
||||
}
|
||||
create("standard") {
|
||||
dimension = "module"
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
compose = true
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":core"))
|
||||
implementation(project(":design_system"))
|
||||
"p3Implementation"(project(":p3"))
|
||||
|
||||
"ps4Implementation"(project(":ps4"))
|
||||
|
||||
implementation(libs.hilt.android)
|
||||
ksp(libs.hilt.compiler)
|
||||
|
||||
implementation(platform(libs.androidx.compose.bom))
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(libs.androidx.compose.material3)
|
||||
implementation(libs.androidx.compose.ui)
|
||||
implementation(libs.androidx.compose.ui.graphics)
|
||||
implementation(libs.androidx.compose.ui.tooling.preview)
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||
implementation("androidx.hilt:hilt-navigation-compose:1.2.0")
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
debugImplementation(libs.androidx.compose.ui.test.manifest)
|
||||
debugImplementation(libs.androidx.compose.ui.tooling)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.example.stage_app
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.example.stage_app", appContext.packageName)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT" />
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent>
|
||||
<package android:name="ir.co.pna.pos" />
|
||||
<intent>
|
||||
<action android:name="ir.co.pna.pos.view.cart.IAPCActivity" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<uses-permission android:name="android.permission.PRINTER" />
|
||||
<uses-permission android:name="com.pos.permission.PRINTER" />
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
<application
|
||||
android:name=".PspApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.PSP"
|
||||
android:usesCleartextTraffic="true">
|
||||
<uses-library android:name="android.device" android:required="false" />
|
||||
|
||||
<activity
|
||||
android:name=".StageMainActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.PSP">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.example.stage_app
|
||||
|
||||
import android.app.Application
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
|
||||
@HiltAndroidApp
|
||||
class PspApplication : Application()
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.example.stage_app
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.SnackbarResult
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.example.design_system.theme.tis.TisTheme
|
||||
import com.example.design_system.util.ObserveAsEvents
|
||||
import com.example.design_system.util.snackbar.SnackbarController
|
||||
import com.example.stage_app.screen.StageWebViewScreen
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@AndroidEntryPoint
|
||||
class StageMainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContent {
|
||||
TisTheme {
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
val snackbarHostState = remember {
|
||||
SnackbarHostState()
|
||||
}
|
||||
ObserveAsEvents(
|
||||
flow = SnackbarController.events,
|
||||
snackbarHostState
|
||||
) { event ->
|
||||
scope.launch {
|
||||
snackbarHostState.currentSnackbarData?.dismiss()
|
||||
val result = snackbarHostState.showSnackbar(
|
||||
message = event.message,
|
||||
actionLabel = event.action?.name,
|
||||
duration = event.duration
|
||||
)
|
||||
|
||||
if (result == SnackbarResult.ActionPerformed) {
|
||||
event.action?.action?.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
snackbarHost = {
|
||||
SnackbarHost(
|
||||
hostState = snackbarHostState
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
|
||||
|
||||
StageWebViewScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.example.stage_app.screen
|
||||
|
||||
import android.provider.Settings
|
||||
import android.webkit.WebView
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.example.design_system.PspWebView
|
||||
import com.example.stage_app.viewmodel.StageViewModel
|
||||
|
||||
private const val tisIp = "192.168.128.73:5000"
|
||||
|
||||
@Composable
|
||||
fun StageWebViewScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: StageViewModel = hiltViewModel()
|
||||
) {
|
||||
|
||||
val context = LocalContext.current
|
||||
var webView: WebView? by remember { mutableStateOf(null) }
|
||||
var currentPaymentId by rememberSaveable { mutableStateOf<String?>(null) }
|
||||
|
||||
// launcher to handle POS app result
|
||||
val posLauncher = rememberLauncherForActivityResult(
|
||||
contract = ActivityResultContracts.StartActivityForResult()
|
||||
) { result ->
|
||||
val paymentResultEntity = viewModel.paymentResult(
|
||||
id = currentPaymentId,
|
||||
activityResult = result
|
||||
|
||||
)
|
||||
webView?.post {
|
||||
webView?.evaluateJavascript(
|
||||
viewModel.postPaymentResult(paymentResultEntity = paymentResultEntity),
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PspWebView(
|
||||
url = tisIp,
|
||||
webView = webView,
|
||||
modifier = modifier,
|
||||
onWebView = { updatedWebView -> webView = updatedWebView },
|
||||
onPayClick = { amount: Long, id: String? ->
|
||||
currentPaymentId = id
|
||||
viewModel.pay(amount)
|
||||
.also(posLauncher::launch)
|
||||
},
|
||||
onPrintClick = { printEntities ->
|
||||
viewModel.print(printEntities)
|
||||
|
||||
},
|
||||
onUUID = {
|
||||
val androidId = Settings
|
||||
.Secure
|
||||
.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
|
||||
|
||||
viewModel.sendAndroidId(
|
||||
androidId
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.example.stage_app.viewmodel
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.example.core.domain.AppConfig
|
||||
import com.example.core.domain.PaymentResult
|
||||
import com.example.core.domain.Printer
|
||||
import com.example.core.domain.PspService
|
||||
import com.example.core.model.PaymentResultEntity
|
||||
import com.example.core.model.PrintEntity
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class StageViewModel @Inject constructor(
|
||||
private val pspService: PspService,
|
||||
private val paymentResult: PaymentResult,
|
||||
private val printer: Printer,
|
||||
private val appConfig: AppConfig
|
||||
) : ViewModel() {
|
||||
|
||||
|
||||
fun postPaymentResult(paymentResultEntity: PaymentResultEntity?): String {
|
||||
return paymentResult.post(paymentResultEntity)
|
||||
}
|
||||
|
||||
fun pay(amount: Long): Intent = pspService.pay(amount)
|
||||
|
||||
fun paymentResult(
|
||||
id: String?,
|
||||
activityResult: ActivityResult
|
||||
): PaymentResultEntity? {
|
||||
return pspService.decodePosResponse(
|
||||
id = id,
|
||||
activityResult = activityResult
|
||||
)
|
||||
}
|
||||
|
||||
private val mock = listOf<PrintEntity>(
|
||||
|
||||
PrintEntity(
|
||||
title = "اطلاعات مشتری",
|
||||
items = listOf(
|
||||
PrintEntity.ItemEntity("نام مشتری", "علی رضایی"),
|
||||
PrintEntity.ItemEntity("شماره تماس", "09123456789"),
|
||||
PrintEntity.ItemEntity("آدرس", "تهران، خیابان ولیعصر، پلاک ۱۲۳")
|
||||
),
|
||||
type = PrintEntity.Type.CARD
|
||||
),
|
||||
PrintEntity(
|
||||
title = "اطلاعات پرداخت",
|
||||
items = listOf(
|
||||
PrintEntity.ItemEntity("روش پرداخت", "کارت به کارت"),
|
||||
PrintEntity.ItemEntity("شماره پیگیری", "7845129630"),
|
||||
PrintEntity.ItemEntity("تاریخ", "1405/02/14")
|
||||
),
|
||||
type = PrintEntity.Type.CARD
|
||||
),
|
||||
)
|
||||
|
||||
fun print(printEntities: List<PrintEntity>) {
|
||||
printer.print(
|
||||
printEntities = printEntities,
|
||||
icon = android.R.drawable.btn_star
|
||||
)
|
||||
}
|
||||
|
||||
fun sendAndroidId(id: String) {
|
||||
appConfig.androidId(id)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
<?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" />
|
||||
</vector>
|
||||
@@ -0,0 +1,30 @@
|
||||
<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>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 982 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
@@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.PSP" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_200</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/black</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_200</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">stage_app</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.PSP" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.example.tis_app.di
|
||||
|
||||
import com.example.core.domain.Printer
|
||||
import com.example.core.domain.PspService
|
||||
import com.example.p3.P3Printer
|
||||
import com.example.p3.P3Service
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
abstract class PspModule {
|
||||
@Binds
|
||||
abstract fun bindPspService(impl: P3Service): PspService
|
||||
|
||||
@Binds
|
||||
abstract fun bindPrinter(impl: P3Printer): Printer
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.example.tis_sep.di
|
||||
|
||||
import com.example.core.PspService
|
||||
import com.example.ps4.Ps4Service
|
||||
import com.example.ps4.P4Printer
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
@@ -12,4 +13,8 @@ import dagger.hilt.components.SingletonComponent
|
||||
abstract class PspModule {
|
||||
@Binds
|
||||
abstract fun bindPspService(impl: Ps4Service): PspService
|
||||
|
||||
@Binds
|
||||
abstract fun bindPrinter(impl: P4Printer): Printer
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.example.stage_app
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
/build
|
||||
@@ -6,7 +6,7 @@ plugins {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.example.tis_sep"
|
||||
namespace = "com.example.tis_app"
|
||||
compileSdk {
|
||||
version = release(36) {
|
||||
minorApiLevel = 1
|
||||
@@ -14,7 +14,7 @@ android {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.example.tis_sep"
|
||||
applicationId = "com.example.tis_app"
|
||||
minSdk = 24
|
||||
targetSdk = 36
|
||||
versionCode = 1
|
||||
@@ -25,7 +25,7 @@ android {
|
||||
|
||||
flavorDimensions.add("module")
|
||||
productFlavors {
|
||||
create("ps3") {
|
||||
create("p3") {
|
||||
dimension = "module"
|
||||
}
|
||||
create("ps4") {
|
||||
@@ -58,11 +58,7 @@ android {
|
||||
dependencies {
|
||||
implementation(project(":core"))
|
||||
implementation(project(":design_system"))
|
||||
"ps3Implementation"(project(":ps3"))
|
||||
"ps3CompileOnly"(files("../ps3/libs/platform_sdk_v2.3.706.jar"))
|
||||
|
||||
// Provide the library for compilation only in the ps3 flavor
|
||||
// "ps3CompileOnly"(files("${rootProject.projectDir}/external_sdks/platform_sdk_v2.3.706.jar"))
|
||||
"p3Implementation"(project(":p3"))
|
||||
|
||||
"ps4Implementation"(project(":ps4"))
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.tis_sep
|
||||
package com.example.tis_app
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
After Width: | Height: | Size: 45 KiB |
@@ -1,4 +1,4 @@
|
||||
package com.example.tis_sep
|
||||
package com.example.tis_app
|
||||
|
||||
import android.app.Application
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.example.tis_sep
|
||||
package com.example.tis_app
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
@@ -15,7 +15,7 @@ import androidx.compose.ui.Modifier
|
||||
import com.example.design_system.theme.tis.TisTheme
|
||||
import com.example.design_system.util.ObserveAsEvents
|
||||
import com.example.design_system.util.snackbar.SnackbarController
|
||||
import com.example.tis_sep.screen.TisWebViewScreen
|
||||
import com.example.tis_app.screen.TisWebViewScreen
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -55,6 +55,8 @@ class TisMainActivity : ComponentActivity() {
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
|
||||
|
||||
TisWebViewScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.example.tis_sep.screen
|
||||
package com.example.tis_app.screen
|
||||
|
||||
import android.provider.Settings
|
||||
import android.webkit.WebView
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
@@ -10,16 +11,18 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.example.design_system.PspWebView
|
||||
import com.example.tis_sep.viewmodel.WebViewModel
|
||||
|
||||
import com.example.tis_app.viewmodel.WebViewModel
|
||||
private const val tisIp = "194.59.214.243:8090"
|
||||
@Composable
|
||||
fun TisWebViewScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: WebViewModel = hiltViewModel()
|
||||
) {
|
||||
|
||||
val context = LocalContext.current
|
||||
var webView: WebView? by remember { mutableStateOf(null) }
|
||||
var currentPaymentId by rememberSaveable { mutableStateOf<String?>(null) }
|
||||
|
||||
@@ -42,7 +45,7 @@ fun TisWebViewScreen(
|
||||
}
|
||||
|
||||
PspWebView(
|
||||
url = "192.168.128.73:5000",
|
||||
url = tisIp,
|
||||
webView = webView,
|
||||
modifier = modifier,
|
||||
onWebView = { updatedWebView -> webView = updatedWebView },
|
||||
@@ -51,6 +54,18 @@ fun TisWebViewScreen(
|
||||
viewModel.pay(amount)
|
||||
.also(posLauncher::launch)
|
||||
},
|
||||
onPrintClick = {},
|
||||
onPrintClick = { printEntities ->
|
||||
viewModel.print(printEntities)
|
||||
|
||||
},
|
||||
onUUID = {
|
||||
val androidId = Settings
|
||||
.Secure
|
||||
.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
|
||||
|
||||
viewModel.sendAndroidId(
|
||||
androidId
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1,18 +1,24 @@
|
||||
package com.example.tis_sep.viewmodel
|
||||
package com.example.tis_app.viewmodel
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.example.core.domain.AppConfig
|
||||
import com.example.core.domain.PaymentResult
|
||||
import com.example.core.domain.Printer
|
||||
import com.example.core.domain.PspService
|
||||
import com.example.core.model.PaymentResultEntity
|
||||
import com.example.core.model.PrintEntity
|
||||
import com.example.tis_app.R
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class WebViewModel @Inject constructor(
|
||||
private val pspService: PspService,
|
||||
private val paymentResult: PaymentResult
|
||||
private val paymentResult: PaymentResult,
|
||||
private val printer: Printer,
|
||||
private val appConfig: AppConfig
|
||||
) : ViewModel() {
|
||||
|
||||
|
||||
@@ -31,4 +37,14 @@ class WebViewModel @Inject constructor(
|
||||
activityResult = activityResult
|
||||
)
|
||||
}
|
||||
fun print(printEntities : List<PrintEntity>) {
|
||||
printer.print(
|
||||
printEntities = printEntities,
|
||||
icon = R.drawable.tis_icon
|
||||
)
|
||||
}
|
||||
|
||||
fun sendAndroidId(id : String) {
|
||||
appConfig.androidId(id)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<!--
|
||||
~ Copyright (C) 2026 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="M17.6,11.48 L19.44,8.3a0.63,0.63 0,0 0,-1.09 -0.63l-1.88,3.24a11.43,11.43 0,0 0,-8.94 0L5.65,7.67a0.63,0.63 0,0 0,-1.09 0.63L6.4,11.48A10.81,10.81 0,0 0,1 20L23,20A10.81,10.81 0,0 0,17.6 11.48ZM7,17.25A1.25,1.25 0,1 1,8.25 16,1.25 1.25,0 0,1 7,17.25ZM17,17.25A1.25,1.25 0,1 1,18.25 16,1.25 1.25,0 0,1 17,17.25Z"/>
|
||||
|
||||
</vector>
|
||||
@@ -0,0 +1,78 @@
|
||||
<?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">
|
||||
<group android:scaleX="1.42"
|
||||
android:scaleY="1.42"
|
||||
android:translateX="-22.68"
|
||||
android:translateY="-22.68">
|
||||
<path android:fillColor="#FFFFFF"
|
||||
android:pathData="M0,0h108v108h-108z"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M19,29L89,29"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M19,39L89,39"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M19,49L89,49"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M19,59L89,59"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M19,69L89,69"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M19,79L89,79"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M29,19L29,89"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M39,19L39,89"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M49,19L49,89"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M59,19L59,89"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M69,19L69,89"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M79,19L79,89"
|
||||
android:strokeColor="#FFFFFF" android:strokeWidth="0.8"/>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -0,0 +1,144 @@
|
||||
<!--
|
||||
~ Copyright (C) 2026 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="237dp"
|
||||
android:height="68dp"
|
||||
android:viewportWidth="237"
|
||||
android:viewportHeight="68">
|
||||
<path
|
||||
android:pathData="M28.5,22.75C32,23 32,23 34,25C34.29,26.85 34.29,26.85 34.34,29.06C34.37,29.86 34.4,30.66 34.43,31.48C34.48,33.16 34.52,34.84 34.57,36.52C34.6,37.32 34.63,38.12 34.66,38.94C34.68,40.03 34.68,40.03 34.71,41.15C34.85,43.25 34.85,43.25 37,45C40.31,41.69 39.4,36.71 39.48,32.21C39.68,26.41 39.68,26.41 41.34,24.28C43,23 43,23 46,22.56C49,23 49,23 50.68,24.45C52.68,28.32 52.32,31.96 52.19,36.25C52.17,37.51 52.17,37.51 52.15,38.8C52.11,40.86 52.06,42.93 52,45C53.32,44.67 54.64,44.34 56,44C56.01,43.43 56.03,42.87 56.04,42.29C56.12,39.73 56.22,37.18 56.31,34.63C56.34,33.74 56.36,32.85 56.38,31.93C56.42,31.08 56.45,30.23 56.49,29.35C56.51,28.57 56.54,27.78 56.57,26.97C57,25 57,25 60,23C63.06,22.75 63.06,22.75 66,23C68.44,25.44 68.29,26.21 68.41,29.57C68.47,30.78 68.47,30.78 68.52,32.02C68.56,33.04 68.59,34.07 68.63,35.13C68.75,38.38 68.87,41.64 69,45C81.38,44.5 81.38,44.5 94,44C94.21,38.21 94.21,38.21 94.39,32.42C94.44,31.34 94.44,31.34 94.49,30.23C94.53,29.12 94.53,29.12 94.57,27.99C95.11,25.49 96,24.56 98,23C100.82,22.85 103.2,23.46 106,24C107.51,25.51 107.2,26.89 107.28,29C107.34,30.21 107.34,30.21 107.39,31.44C107.46,33.15 107.54,34.85 107.61,36.56C107.66,37.77 107.66,37.77 107.72,39C107.75,39.74 107.78,40.49 107.81,41.25C107.82,43.03 107.82,43.03 109,44C111.38,44.09 113.72,44.12 116.1,44.1C116.81,44.1 117.52,44.09 118.25,44.09C120.52,44.09 122.79,44.08 125.06,44.06C126.6,44.06 128.14,44.05 129.67,44.05C133.45,44.04 137.22,44.02 141,44C142.12,41.76 142.19,40.35 142.32,37.87C142.36,37.06 142.4,36.26 142.44,35.43C142.48,34.58 142.52,33.74 142.56,32.88C142.63,31.6 142.63,31.6 142.69,30.3C142.8,28.2 142.9,26.1 143,24C146.01,22.49 148.68,22.82 152,23C155.33,26.33 154.37,30.67 154.38,35.19C154.4,36.12 154.42,37.06 154.45,38.02C154.48,44.23 153.79,48.01 150,53C145.51,56.61 141.37,56.42 135.87,56.36C134.56,56.36 134.56,56.36 133.22,56.36C131.38,56.36 129.54,56.35 127.7,56.34C124.88,56.31 122.06,56.32 119.24,56.32C117.45,56.32 115.66,56.31 113.87,56.3C113.02,56.3 112.18,56.3 111.31,56.3C107.38,56.26 105.35,56.23 102,54C101.49,54.33 100.98,54.65 100.45,54.99C97.13,56.36 94.34,56.24 90.75,56.23C90.05,56.23 89.36,56.23 88.64,56.23C87.18,56.23 85.71,56.22 84.25,56.21C82.01,56.19 79.77,56.19 77.53,56.19C66.49,56.15 66.49,56.15 62,55C61.01,55.49 61.01,55.49 60,56C58.21,56.1 56.42,56.13 54.63,56.13C53.67,56.13 52.71,56.13 51.73,56.13C49,56 49,56 46.77,55.43C44.91,54.78 44.91,54.78 43,56C40.7,56.23 38.4,56.38 36.09,56.52C33.61,56.84 33.61,56.84 32,60C31.34,60 30.68,60 30,60C29.67,60.99 29.34,61.98 29,63C24.4,65.77 19.14,65.37 13.94,65.38C12.59,65.41 12.59,65.41 11.22,65.45C4.68,65.48 4.68,65.48 1.38,63.14C0,61 0,61 0.06,58.38C1,56 1,56 4,54C6.71,53.72 9.35,53.54 12.06,53.44C17.19,53.43 17.19,53.43 22,52C22.02,51.19 22.04,50.39 22.06,49.55C22.16,45.91 22.26,42.27 22.38,38.63C22.42,36.72 22.42,36.72 22.47,34.77C22.51,33.56 22.55,32.35 22.59,31.1C22.62,29.98 22.65,28.86 22.68,27.71C23.18,23.44 24.29,23.05 28.5,22.75Z"
|
||||
android:fillColor="#0A774D"/>
|
||||
<path
|
||||
android:pathData="M184,0C186.89,-0.12 188.37,-0.09 191,1C194.04,4.06 196.47,7.52 199,11C202.48,15.62 202.48,15.62 207,19C207,19.99 207,20.98 207,22C207.99,22.33 208.98,22.66 210,23C211.87,25.07 211.87,25.07 213.88,27.69C216.17,30.67 218.47,33.52 221.06,36.25C223,39 223,39 223.13,42.06C221.72,45.72 220.03,47.54 217,50C214.69,50.81 214.69,50.81 213,51C213.1,51.72 213.21,52.44 213.31,53.19C212.87,57.17 211.01,58.48 208,61C206.51,61.49 206.51,61.49 205,62C203.77,65.01 203.77,65.01 203,68C199.37,68 195.74,68 192,68C194.03,63.95 195.89,61.05 200,59C201.01,57.25 202.01,55.49 202.99,53.72C204.12,51.79 205.19,50.34 207,49C207.99,49 208.98,49 210,49C210.62,45.56 211,42.51 211,39C209.71,37.09 209.71,37.09 208,35.38C205,32.19 205,32.19 205,30C204.34,30 203.68,30 203,30C201.77,28.31 200.55,26.61 199.37,24.88C197.89,22.75 197.89,22.75 195.25,20.25C193,18 193,18 192,15C191.34,15 190.68,15 190,15C187.27,12.27 184.97,9.32 183,6C183.06,2.44 183.06,2.44 184,0Z"
|
||||
android:fillColor="#11754D"/>
|
||||
<path
|
||||
android:pathData="M201,0C203.63,0.38 203.63,0.38 206,1C206.33,1.99 206.66,2.98 207,4C207.66,4 208.32,4 209,4C209.34,5.39 209.34,5.39 209.69,6.81C211.25,10.62 212.51,11.04 216,13C217.02,14.65 218.03,16.32 219,18C219.99,18.33 220.98,18.66 222,19C227,24.47 227,24.47 227,27C227.66,27 228.32,27 229,27C233,31.47 233,31.47 233,34C234.32,34.66 235.64,35.32 237,36C237.49,43.22 237.49,43.22 235.13,47C233,49 233,49 231,49C230.77,49.7 230.55,50.39 230.32,51.11C228.71,54.63 226.46,57.31 223.94,60.19C220.63,63.86 220.63,63.86 218,68C214.7,68 211.4,68 208,68C209,64 209,64 211,61C211.66,61 212.32,61 213,61C213.37,60.19 213.37,60.19 213.75,59.36C215.28,56.47 217.09,53.9 219,51.25C219.7,50.27 220.4,49.28 221.13,48.27C221.74,47.52 222.36,46.77 223,46C223.66,46 224.32,46 225,46C225.33,44.68 225.66,43.36 226,42C226.66,42 227.32,42 228,42C227.53,41.24 227.05,40.47 226.56,39.69C225,37 225,37 224,34C223.34,34 222.68,34 222,34C220.27,32.14 220.27,32.14 218.38,29.69C217.74,28.89 217.11,28.09 216.46,27.26C215,25 215,25 215,22C213.68,22 212.36,22 211,22C208.75,19.75 208.75,19.75 207,17C207,15.68 207,14.36 207,13C206.24,12.75 205.47,12.51 204.69,12.25C201.68,10.85 200.57,9.9 199,7C198.69,4.38 198.69,4.38 199,2C199.66,1.34 200.32,0.68 201,0Z"
|
||||
android:fillColor="#10744D"/>
|
||||
<path
|
||||
android:pathData="M161,19C163.31,19 163.31,19 166,20C167.29,21.42 168.58,22.85 169.73,24.38C171.15,26.27 171.15,26.27 173.75,28.69C176,31 176,31 177,34C177.99,34.33 178.98,34.66 180,35C181.47,42.1 181.47,42.1 179.19,46.5C178.1,47.74 178.1,47.74 177,49C176.34,49 175.68,49 175,49C174.77,49.7 174.55,50.4 174.31,51.13C172.66,54.74 170.71,57.09 168,60C167.34,60 166.68,60 166,60C165.73,60.76 165.46,61.53 165.19,62.31C164,65 163.3,66.23 161,68C158.52,68.29 158.52,68.29 155.81,68.19C154.91,68.16 154.01,68.13 153.08,68.11C152.39,68.07 151.71,68.04 151,68C152.73,63.96 155.46,60.71 158.19,57.31C159.18,56.07 160.17,54.82 161.16,53.57C161.88,52.66 161.88,52.66 162.62,51.74C164.49,49.38 166.34,47 168.19,44.63C168.74,43.92 169.29,43.21 169.86,42.48C170.23,41.99 170.61,41.5 171,41C169.45,37.53 167.38,34.77 165,31.81C164.3,30.93 163.6,30.05 162.88,29.14C161.18,26.93 161.18,26.93 159,26C158.88,23.63 158.88,23.63 159,21C159.66,20.34 160.32,19.68 161,19Z"
|
||||
android:fillColor="#57BF7A"/>
|
||||
<path
|
||||
android:pathData="M176.56,18.94C177.77,18.97 177.77,18.97 179,19C179.27,19.64 179.54,20.28 179.81,20.94C180.89,23.33 180.89,23.33 184,24C185.94,26.18 185.94,26.18 188,28.88C190.63,32.39 190.63,32.39 193.75,35.45C195,37 195,37 195.6,39.66C194.69,44.71 191.71,47.61 188.38,51.38C187.13,52.82 185.89,54.26 184.65,55.71C184.03,56.42 183.42,57.12 182.79,57.84C180.5,60.6 178.5,63.52 176.53,66.5C174.45,68.53 172.97,68.48 170.13,68.5C168.75,68.37 167.37,68.22 166,68C166.61,64.04 168.6,61.45 170.94,58.25C171.65,57.27 172.36,56.28 173.09,55.27C174.04,54.14 174.04,54.14 175,53C175.66,53 176.32,53 177,53C177.33,51.68 177.66,50.36 178,49C178.66,49 179.32,49 180,49C180.27,48.44 180.54,47.89 180.81,47.31C182.1,44.8 183.54,42.41 185,40C183.56,38.23 182.13,36.46 180.69,34.69C179.89,33.7 179.09,32.72 178.26,31.7C176.17,29.09 176.17,29.09 174.22,27.34C173,26 173,26 172.75,22.88C173.09,19.02 173.09,19.02 176.56,18.94Z"
|
||||
android:fillColor="#54C079"/>
|
||||
<path
|
||||
android:pathData="M188,19C190.09,18.55 190.09,18.55 193,19C195.53,21.14 197.54,23.68 199.63,26.25C200.2,26.93 200.77,27.61 201.36,28.32C202.93,30.2 204.48,32.08 206,34C206.56,34.69 207.12,35.37 207.69,36.08C209,38 209,38 208.9,40.42C207.85,43.44 206.42,45.7 204.56,48.31C203.95,49.2 203.33,50.08 202.69,50.99C202.13,51.65 201.58,52.32 201,53C200.34,53 199.68,53 199,53C199,53.99 199,54.98 199,56C197.36,57.69 195.69,59.35 194,61C193.26,62.27 192.53,63.54 191.81,64.81C190.6,66.62 190.6,66.62 189,68C185.59,68.6 182.42,68.42 179,68C180.21,64.56 181.39,62.5 184,60C184.33,59.01 184.66,58.02 185,57C186.64,55.3 188.31,53.64 190,52C191.65,50.17 193.28,48.32 194.88,46.44C195.68,45.51 196.48,44.58 197.3,43.62C199.27,41.19 199.27,41.19 198.76,38.66C198.51,38.11 198.26,37.56 198,37C197.34,37 196.68,37 196,37C192,32.53 192,32.53 192,30C191.01,29.67 190.02,29.34 189,29C187.19,26.75 187.19,26.75 186,24C186.81,21.19 186.81,21.19 188,19Z"
|
||||
android:fillColor="#54BF78"/>
|
||||
<path
|
||||
android:pathData="M8,4C10.38,4.31 10.38,4.31 13,5C15,8 15,8 15,12C16.32,12 17.64,12 19,12C19.66,10.68 20.32,9.36 21,8C21.66,8 22.32,8 23,8C23,7.34 23,6.68 23,6C27.75,6.88 27.75,6.88 30,8C30,9.32 30,10.64 30,12C32.97,12 35.94,12 39,12C38.5,11.01 38.5,11.01 38,10C36.02,10 34.04,10 32,10C32,8.68 32,7.36 32,6C33.65,5.97 35.29,5.95 36.94,5.94C38.31,5.92 38.31,5.92 39.71,5.9C42,6 42,6 43,7C43.04,8.67 43.04,10.33 43,12C44.98,12 46.96,12 49,12C49,11.34 49,10.68 49,10C47.68,10 46.36,10 45,10C45,8.68 45,7.36 45,6C48.96,6 52.92,6 57,6C57,7.32 57,8.64 57,10C55.68,10 54.36,10 53,10C53,10.66 53,11.32 53,12C58.43,11.62 60.33,9.87 64,6C64.99,6 65.98,6 67,6C67,6.66 67,7.32 67,8C67.99,8.33 68.98,8.66 70,9C70.94,10.81 70.94,10.81 71,13C69.5,15.31 69.5,15.31 67,17C64.66,16.71 62.33,16.36 60,16C56.87,15.85 53.75,15.86 50.63,15.88C49.76,15.88 48.89,15.88 48,15.88C41.44,15.92 34.92,16.21 28.38,16.73C24.98,16.99 22.27,16.89 19,16C16.79,15.96 14.58,15.96 12.38,16C6.22,16.11 6.22,16.11 4,15C4,14.01 4,13.02 4,12C6.64,12 9.28,12 12,12C11.01,10.58 11.01,10.58 10,9.13C8,6 8,6 8,4ZM23,11C23.33,11.66 23.66,12.32 24,13C24.99,12.67 25.98,12.34 27,12C25.68,11.67 24.36,11.34 23,11ZM64,11C64,11.66 64,12.32 64,13C64.99,12.67 65.98,12.34 67,12C66.01,11.67 65.02,11.34 64,11Z"
|
||||
android:fillColor="#19704E"/>
|
||||
<path
|
||||
android:pathData="M119.94,28.88C121.29,28.91 122.65,28.95 124,29C125.73,29 127.46,28.99 129.19,28.93C129.97,28.91 130.76,28.89 131.56,28.88C132.74,28.84 132.74,28.84 133.94,28.8C136,29 136,29 138,31C138.32,35.34 138.45,37.33 136,41C133.97,41.37 133.97,41.37 131.5,41.36C130.61,41.36 129.73,41.36 128.81,41.36C127.42,41.34 127.42,41.34 126,41.31C125.07,41.32 124.14,41.32 123.19,41.32C116.27,41.27 116.27,41.27 114,39C113.73,37.13 113.73,37.13 113.75,35C113.74,34.3 113.74,33.6 113.73,32.88C114.3,28.85 116.18,28.99 119.94,28.88Z"
|
||||
android:fillColor="#10734D"/>
|
||||
<path
|
||||
android:pathData="M70,57C72.06,56.71 72.06,56.71 74.44,56.81C75.61,56.85 75.61,56.85 76.81,56.89C77.53,56.93 78.25,56.96 79,57C80.74,57 82.48,56.99 84.23,56.96C85.02,56.96 85.81,56.95 86.63,56.94C87.42,56.93 88.22,56.91 89.04,56.9C91,57 91,57 92,58C92.07,59.69 92.08,61.38 92.06,63.06C92.05,63.98 92.04,64.9 92.04,65.85C92.02,66.56 92.01,67.27 92,68C88.19,68.03 84.38,68.05 80.56,68.06C79.47,68.07 78.39,68.08 77.26,68.09C76.23,68.09 75.19,68.09 74.13,68.1C72.69,68.11 72.69,68.11 71.22,68.11C69,68 69,68 68,67C67.64,60.54 67.64,60.54 70,57Z"
|
||||
android:fillColor="#0D744C"/>
|
||||
<path
|
||||
android:pathData="M192,35C195,37 195,37 195.6,39.6C194.7,44.69 191.74,47.57 188.38,51.38C187.13,52.82 185.89,54.26 184.65,55.71C183.73,56.77 183.73,56.77 182.79,57.84C180.5,60.6 178.5,63.52 176.53,66.5C174.45,68.53 172.97,68.48 170.13,68.5C168.75,68.37 167.37,68.22 166,68C166.61,64.04 168.6,61.45 170.94,58.25C172,56.77 172,56.77 173.09,55.27C173.72,54.52 174.35,53.77 175,53C175.66,53 176.32,53 177,53C177.33,51.68 177.66,50.36 178,49C178.66,49 179.32,49 180,49C180.25,48.48 180.49,47.97 180.75,47.44C182.4,44.23 184.2,41.12 186,38C186.66,39.77 186.66,39.77 187,42C186.03,43.82 186.03,43.82 184.5,45.69C183.94,46.38 183.39,47.07 182.82,47.79C182.22,48.52 181.62,49.25 181,50C179.81,51.54 178.62,53.08 177.44,54.63C174.69,58.14 171.88,61.59 169,65C169.99,65.33 170.98,65.66 172,66C178.59,59.6 184.02,52.71 189.27,45.16C189.84,44.45 190.41,43.73 191,43C191.66,43 192.32,43 193,43C192.67,40.36 192.34,37.72 192,35Z"
|
||||
android:fillColor="#60BB7E"/>
|
||||
<path
|
||||
android:pathData="M117,6C117.99,6.33 118.98,6.66 120,7C120,8.65 120,10.3 120,12C123.3,12 126.6,12 130,12C130.33,10.02 130.66,8.04 131,6C131.99,6 132.98,6 134,6C134.29,12.05 134.29,12.05 134,14C130.58,16.28 129.32,16.22 125.31,16.13C123.82,16.1 123.82,16.1 122.3,16.07C121.54,16.05 120.78,16.02 120,16C119.9,16.62 119.79,17.24 119.69,17.88C119,20 119,20 116,22C113.81,21.63 113.81,21.63 112,21C112.33,20.01 112.66,19.02 113,18C113.99,17.67 114.98,17.34 116,17C116.33,13.37 116.66,9.74 117,6Z"
|
||||
android:fillColor="#166E4C"/>
|
||||
<path
|
||||
android:pathData="M83.63,5.88C84.41,5.92 85.19,5.96 86,6C86.33,6.99 86.66,7.98 87,9C85.35,9.33 83.7,9.66 82,10C82,10.66 82,11.32 82,12C83.65,12 85.3,12 87,12C87.04,14 87.04,16 87,18C85.33,19.67 83.34,19.21 81.06,19.25C80.17,19.28 79.27,19.3 78.35,19.33C77.57,19.22 76.8,19.11 76,19C73.57,15.36 73.84,13.29 74,9C74.66,8.67 75.32,8.34 76,8C76.66,8.33 77.32,8.66 78,9C78,10.98 78,12.96 78,15C78.33,14.67 78.66,14.34 79,14C78.98,13.03 78.96,12.06 78.94,11.06C79.02,7.14 79.63,6.07 83.63,5.88Z"
|
||||
android:fillColor="#19714F"/>
|
||||
<path
|
||||
android:pathData="M198,37C198.99,37.33 199.98,37.66 201,38C200.53,42.81 198.2,45.8 195.25,49.44C194.82,49.98 194.39,50.53 193.95,51.1C191.76,53.86 189.53,56.55 187.23,59.22C184.86,61.85 184.86,61.85 184,65C185.32,65.33 186.64,65.66 188,66C188,65.34 188,64.68 188,64C188.66,64 189.32,64 190,64C190.25,63.46 190.49,62.93 190.75,62.38C194.98,54.34 194.98,54.34 199,53C199,56 199,56 196.81,58.25C195.88,59.16 194.96,60.07 194,61C193.26,62.27 192.53,63.54 191.81,64.81C190.6,66.62 190.6,66.62 189,68C185.59,68.6 182.42,68.42 179,68C180.21,64.56 181.39,62.5 184,60C184.33,59.01 184.66,58.02 185,57C186.64,55.3 188.31,53.64 190,52C191.65,50.17 193.28,48.32 194.88,46.44C195.68,45.51 196.48,44.58 197.3,43.62C199.27,41.19 199.27,41.19 198.76,38.66C198.51,38.11 198.26,37.56 198,37Z"
|
||||
android:fillColor="#5EBA7D"/>
|
||||
<path
|
||||
android:pathData="M141,4C144.02,4.33 145.6,4.61 147.81,6.75C149.23,9.44 149.47,11 149,14C145.55,16.3 144.05,16.34 140,16C139.34,15.34 138.68,14.68 138,14C138.3,9.86 138.68,7.48 141,4ZM143,9C143,10.32 143,11.64 143,13C143.66,12.67 144.32,12.34 145,12C144.67,11.01 144.34,10.02 144,9C143.67,9 143.34,9 143,9Z"
|
||||
android:fillColor="#1A714E"/>
|
||||
<path
|
||||
android:pathData="M93,3C94.32,3 95.64,3 97,3C97.11,5.42 97.19,7.83 97.25,10.25C97.3,11.27 97.3,11.27 97.35,12.32C97.42,15.75 97.24,17.66 95.23,20.48C93,22 93,22 89,22C89.38,20.06 89.38,20.06 90,18C90.66,17.67 91.32,17.34 92,17C92.47,13.72 92.47,13.72 92.63,9.94C92.7,8.65 92.77,7.36 92.85,6.03C92.9,5.03 92.95,4.03 93,3Z"
|
||||
android:fillColor="#18724F"/>
|
||||
<path
|
||||
android:pathData="M172,4C174.38,4.31 174.38,4.31 177,5C179.3,8.45 179.34,9.95 179,14C177,16 177,16 173.56,16.25C170,16 170,16 167,14C167,13.34 167,12.68 167,12C169.64,12 172.28,12 175,12C174.51,11.05 174.01,10.1 173.5,9.13C172,6 172,6 172,4Z"
|
||||
android:fillColor="#1D7651"/>
|
||||
<path
|
||||
android:pathData="M107,4C111.58,4.48 111.58,4.48 113.38,6.69C114.21,9.76 113.81,11.94 113,15C110.48,16.26 109.15,15.92 106.38,15.56C105.56,15.46 104.74,15.36 103.9,15.25C103.27,15.17 102.65,15.09 102,15C102,14.01 102,13.02 102,12C104.64,12 107.28,12 110,12C109.5,11.05 109.01,10.1 108.5,9.13C107,6 107,6 107,4Z"
|
||||
android:fillColor="#1B7250"/>
|
||||
<path
|
||||
android:pathData="M120.56,30.94C121.7,30.96 122.83,30.98 124,31C124.13,38.75 124.13,38.75 123,41C120.63,41.19 120.63,41.19 118,41C115.71,37.56 115.74,36.03 116,32C117,31 117,31 120.56,30.94Z"
|
||||
android:fillColor="#09774D"/>
|
||||
<path
|
||||
android:pathData="M155,4C156.32,4 157.64,4 159,4C161.68,8.02 161.16,10.24 161,15C158.48,16.26 157.15,15.92 154.38,15.56C153.56,15.46 152.74,15.36 151.9,15.25C151.27,15.17 150.65,15.09 150,15C150,14.01 150,13.02 150,12C152.64,12 155.28,12 158,12C157.51,11.24 157.01,10.47 156.5,9.69C155,7 155,7 155,4Z"
|
||||
android:fillColor="#187450"/>
|
||||
<path
|
||||
android:pathData="M23,49C23.33,49 23.66,49 24,49C24,50.65 24,52.3 24,54C20.18,56.47 16.15,56.44 11.75,56.63C11,56.66 10.26,56.7 9.49,56.74C7.66,56.84 5.83,56.92 4,57C3.67,58.32 3.34,59.64 3,61C4.32,61.99 5.64,62.98 7,64C4.63,64.19 4.63,64.19 2,64C0,61 0,61 0.19,58.44C1,56 1,56 4,54C6.71,53.72 9.35,53.54 12.06,53.44C17.19,53.43 17.19,53.43 22,52C22.33,51.01 22.66,50.02 23,49Z"
|
||||
android:fillColor="#16734E"/>
|
||||
<path
|
||||
android:pathData="M163,1C163.99,1 164.98,1 166,1C166,6.28 166,11.56 166,17C164.68,16.67 163.36,16.34 162,16C161.97,13.69 161.95,11.38 161.94,9.06C161.93,7.77 161.91,6.49 161.9,5.16C162,2 162,2 163,1Z"
|
||||
android:fillColor="#167650"/>
|
||||
<path
|
||||
android:pathData="M98,1C98.99,1 99.98,1 101,1C101,6.28 101,11.56 101,17C100.01,17 99.02,17 98,17C98,11.72 98,6.44 98,1Z"
|
||||
android:fillColor="#15704D"/>
|
||||
<path
|
||||
android:pathData="M203,61C204.13,65.75 204.13,65.75 203,68C200.36,68 197.72,68 195,68C195.91,62.69 197.53,61 203,61Z"
|
||||
android:fillColor="#0D744B"/>
|
||||
<path
|
||||
android:pathData="M32,6C35.3,6 38.6,6 42,6C42.33,6.99 42.66,7.98 43,9C42.01,10.49 42.01,10.49 41,12C40.34,12 39.68,12 39,12C38.67,11.34 38.34,10.68 38,10C36.02,10 34.04,10 32,10C32,8.68 32,7.36 32,6Z"
|
||||
android:fillColor="#1E7152"/>
|
||||
<path
|
||||
android:pathData="M211,50C212.25,52.49 211.78,53.41 211,56C210.34,56 209.68,56 209,56C208.34,57.32 207.68,58.64 207,60C205.68,59.67 204.36,59.34 203,59C203.34,55.83 204,55 206.44,52.81C209,51 209,51 211,50Z"
|
||||
android:fillColor="#0A774C"/>
|
||||
<path
|
||||
android:pathData="M202,2C203.94,2.81 203.94,2.81 206,4C206.33,4.99 206.66,5.98 207,7C207.66,7 208.32,7 209,7C208.67,8.32 208.34,9.64 208,11C205.68,10.6 204.14,10.09 202.19,8.75C201,7 201,7 201.31,4.31C201.54,3.55 201.77,2.79 202,2Z"
|
||||
android:fillColor="#0A774D"/>
|
||||
<path
|
||||
android:pathData="M176.56,18.94C177.77,18.97 177.77,18.97 179,19C179,19.66 179,20.32 179,21C177.68,21 176.36,21 175,21C175.66,23.31 176.32,25.62 177,28C177.66,28 178.32,28 179,28C180.69,29.81 180.69,29.81 182,32C181.67,32.99 181.34,33.98 181,35C179.65,33.64 178.32,32.26 177,30.88C176.26,30.11 175.51,29.34 174.75,28.55C172.62,25.45 172.58,23.69 173,20C174,19 174,19 176.56,18.94Z"
|
||||
android:fillColor="#5CB879"/>
|
||||
<path
|
||||
android:pathData="M70,57C72.16,56.71 72.16,56.71 74.63,56.81C75.44,56.84 76.26,56.87 77.1,56.89C78.04,56.95 78.04,56.95 79,57C79.33,57.66 79.66,58.32 80,59C76.7,59 73.4,59 70,59C70.48,63.65 70.48,63.65 72,68C70.68,67.67 69.36,67.34 68,67C67.75,60.38 67.75,60.38 70,57Z"
|
||||
android:fillColor="#146A47"/>
|
||||
<path
|
||||
android:pathData="M188,19C189.32,19 190.64,19 192,19C192.33,19.99 192.66,20.98 193,22C192.01,22.66 191.02,23.32 190,24C190.66,25.65 191.32,27.3 192,29C191.01,29 190.02,29 189,29C187.19,26.81 187.19,26.81 186,24C186.81,21.19 186.81,21.19 188,19Z"
|
||||
android:fillColor="#5DB87C"/>
|
||||
<path
|
||||
android:pathData="M127.06,16.94C128.52,16.97 128.52,16.97 130,17C130,18.32 130,19.64 130,21C129.34,21 128.68,21 128,21C128,21.66 128,22.32 128,23C126.68,23 125.36,23 124,23C123.62,21.34 123.29,19.68 123,18C124,17 124,17 127.06,16.94Z"
|
||||
android:fillColor="#1F7354"/>
|
||||
<path
|
||||
android:pathData="M152,43C152.66,43 153.32,43 154,43C153.26,48.16 151.75,51.65 147.56,54.88C144.66,56.15 143.9,55.9 141,55C141.54,54.72 142.09,54.44 142.64,54.15C148.04,51.13 150.14,48.91 152,43Z"
|
||||
android:fillColor="#157551"/>
|
||||
<path
|
||||
android:pathData="M49,53C49.66,53.33 50.32,53.66 51,54C52.37,54.07 53.75,54.08 55.13,54.06C57.04,54.03 57.04,54.03 59,54C59,54.66 59,55.32 59,56C57.42,56.03 55.83,56.05 54.25,56.06C52.93,56.08 52.93,56.08 51.58,56.1C49.21,56.01 47.29,55.57 45,55C42.99,55.27 40.99,55.59 39,56C41.21,51.59 44.68,51.75 49,53Z"
|
||||
android:fillColor="#15744E"/>
|
||||
<path
|
||||
android:pathData="M205,30C205.66,30 206.32,30 207,30C207,30.66 207,31.32 207,32C207.66,32 208.32,32 209,32C213,36.47 213,36.47 213,39C213.99,39.33 214.98,39.66 216,40C215.01,41.49 215.01,41.49 214,43C212,42 212,42 211.19,39.75C209.74,36.39 207.6,34.53 205,32C205,31.34 205,30.68 205,30Z"
|
||||
android:fillColor="#19734F"/>
|
||||
<path
|
||||
android:pathData="M33,55C33.66,55.33 34.32,55.66 35,56C33.63,58 33.63,58 32,60C31.34,60 30.68,60 30,60C29.67,60.99 29.34,61.98 29,63C25.44,64.19 25.44,64.19 22,65C22,64.34 22,63.68 22,63C22.89,62.61 23.77,62.22 24.69,61.81C28.12,59.93 30.37,57.87 33,55Z"
|
||||
android:fillColor="#14744F"/>
|
||||
<path
|
||||
android:pathData="M131,6C131.99,6 132.98,6 134,6C134,8.64 134,11.28 134,14C132.35,14.33 130.7,14.66 129,15C129.35,14.4 129.7,13.8 130.06,13.19C131.33,10.89 131.33,10.89 130,8C130.33,7.34 130.66,6.68 131,6Z"
|
||||
android:fillColor="#1C7451"/>
|
||||
<path
|
||||
android:pathData="M28.56,22.94C29.7,22.96 30.83,22.98 32,23C32.66,24.32 33.32,25.64 34,27C33.01,27.49 33.01,27.49 32,28C32,27.01 32,26.02 32,25C27.39,26.21 27.39,26.21 23,28C24.13,23.02 24.13,23.02 28.56,22.94Z"
|
||||
android:fillColor="#16704D"/>
|
||||
<path
|
||||
android:pathData="M206,43C206,46.34 205.52,47.07 203.63,49.69C203.18,50.31 202.74,50.93 202.29,51.57C201.86,52.04 201.44,52.52 201,53C200.34,53 199.68,53 199,53C200.39,48.57 202.61,46.13 206,43Z"
|
||||
android:fillColor="#5CB57B"/>
|
||||
<path
|
||||
android:pathData="M161,19C163.63,19.38 163.63,19.38 166,20C165.67,20.66 165.34,21.32 165,22C163.68,22 162.36,22 161,22C161,23.32 161,24.64 161,26C160.34,26 159.68,26 159,26C158.88,23.63 158.88,23.63 159,21C159.66,20.34 160.32,19.68 161,19Z"
|
||||
android:fillColor="#5DB97B"/>
|
||||
<path
|
||||
android:pathData="M180,39C180.75,40.63 180.75,40.63 181,43C179.19,46.25 179.19,46.25 177,49C176.34,49 175.68,49 175,49C175.61,45.01 177.71,42.26 180,39Z"
|
||||
android:fillColor="#5EBC7E"/>
|
||||
<path
|
||||
android:pathData="M176.56,18.94C177.77,18.97 177.77,18.97 179,19C179,19.66 179,20.32 179,21C177.68,21 176.36,21 175,21C175,22.65 175,24.3 175,26C174.34,26 173.68,26 173,26C172.96,24 172.96,22 173,20C174,19 174,19 176.56,18.94Z"
|
||||
android:fillColor="#65BB7F"/>
|
||||
<path
|
||||
android:pathData="M150,12C152.48,12.49 152.48,12.49 155,13C155,13.99 155,14.98 155,16C153.35,15.67 151.7,15.34 150,15C150,14.01 150,13.02 150,12Z"
|
||||
android:fillColor="#1E7855"/>
|
||||
</vector>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 6.9 KiB |