Replace Skip implementation with Kotlin Multiplatform implementation

This commit is contained in:
2026-09-02 22:11:32 +03:00
parent 902b683779
commit abf7cf2e83
184 changed files with 7163 additions and 2449 deletions
+58
View File
@@ -0,0 +1,58 @@
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
alias(libs.plugins.mokoResources)
}
kotlin {
js {
browser()
binaries.executable()
}
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
binaries.executable()
}
sourceSets {
commonMain.dependencies {
implementation(project(":shared"))
implementation(libs.compose.ui)
implementation(npm("@js-joda/timezone", "2.25.1"))
}
}
}
multiplatformResources {
resourcesPackage.set("xyz.tyiu.satsprice.webApp")
}
// moko-resources loads string/plural/image/file resources at runtime via fetch('./localization/...'),
// not via a webpack import, so webpack's production bundler has no reason to know that directory
// exists and never copies it into the distribution. (The dev server happens to serve it anyway, since
// it serves the whole compiled package directory as static files — which is why this only breaks in
// production.) Copy it into the actual distribution output ourselves so a static production build is
// self-contained.
val npmPackageName = "${rootProject.name}-${project.name}"
mapOf(
"wasmJsBrowserDistribution" to "wasm",
"jsBrowserDistribution" to "js",
).forEach { (taskName, targetDir) ->
tasks.named<Sync>(taskName) {
val localizationSrc = rootProject.layout.buildDirectory
.dir("$targetDir/packages/$npmPackageName/kotlin/localization")
doLast {
val src = localizationSrc.get().asFile
if (src.exists()) {
src.copyRecursively(outputs.files.singleFile.resolve("localization"), overwrite = true)
}
}
}
}
@@ -0,0 +1,21 @@
// workaround from https://github.com/ryanclark/karma-webpack/issues/498#issuecomment-790040818
const output = {
path: require("os").tmpdir() + '/' + '_karma_webpack_' + Math.floor(Math.random() * 1000000),
}
const optimization = {
runtimeChunk: true
}
config.set(
{
webpack: {... createWebpackConfig(), output, optimization},
files: config.files.concat([{
pattern: `${output.path}/**/*`,
watched: false,
included: false,
}]
)
}
)
@@ -0,0 +1,17 @@
package xyz.tyiu.satsprice
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.window.ComposeViewport
@OptIn(ExperimentalWasmJsInterop::class)
@JsModule("@js-joda/timezone")
external object JsJodaTimeZoneModule
private val jsJodaTz = JsJodaTimeZoneModule
@OptIn(ExperimentalComposeUiApi::class)
fun main() {
ComposeViewport {
App()
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

+22
View File
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SatsPrice</title>
<link type="text/css" rel="stylesheet" href="styles.css">
<link rel="icon" href="favicon.ico" sizes="any">
<link rel="icon" type="image/png" href="favicon-192.png" sizes="192x192">
</head>
<body style="text-align: center; align-content: center">
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 50 50" role="presentation">
<circle cx="25" cy="25" r="20" stroke="#ccc" stroke-width="4" fill="none"/>
<circle cx="25" cy="25" r="20" stroke="#333" stroke-width="4" fill="none" stroke-linecap="round"
stroke-dasharray="90 125">
<animateTransform attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="1s"
repeatCount="indefinite"/>
</circle>
</svg>
<script type="application/javascript" src="webApp.js"></script>
</body>
</html>
+7
View File
@@ -0,0 +1,7 @@
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
@@ -0,0 +1,39 @@
// noinspection JSUnnecessarySemicolon
;(function(config) {
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
config.module.rules.push(
{
test: /\.(.*)/,
resource: [
path.resolve(__dirname, "kotlin/assets"),
path.resolve(__dirname, "kotlin/files"),
path.resolve(__dirname, "kotlin/images"),
path.resolve(__dirname, "kotlin/localization"),
],
type: 'asset/resource'
}
);
config.plugins.push(new MiniCssExtractPlugin())
config.module.rules.push(
{
test: /\.css$/,
resource: [
path.resolve(__dirname, "kotlin/fonts"),
],
use: ['style-loader', 'css-loader']
}
)
config.module.rules.push(
{
test: /\.(otf|ttf)?$/,
resource: [
path.resolve(__dirname, "kotlin/fonts"),
],
type: 'asset/resource',
}
)
})(config);