Compare commits
31 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4fb6a25be | ||
|
|
2eeebee36d | ||
|
|
616a7a9a95 | ||
|
|
d0887d88ba | ||
|
|
ae845d422c | ||
|
|
5c1b8b3cc8 | ||
|
|
3e2fcf87a8 | ||
|
|
03b90e2afe | ||
|
|
58f493e561 | ||
|
|
629ae6899a | ||
|
|
f6d754ff0a | ||
|
|
2ccdb02ba7 | ||
|
|
0784d7ce3f | ||
|
|
9a9b42a88c | ||
|
|
8bc24446fa | ||
|
|
fc4451bfbc | ||
|
|
6e5fd227bf | ||
|
|
e873f14a7b | ||
|
|
b7bff1a7bd | ||
|
|
7056758728 | ||
|
|
65962f3581 | ||
|
|
472654180a | ||
|
|
3a7a92800b | ||
|
|
892448c57f | ||
|
|
5be2247cb4 | ||
|
|
5b4798b7b2 | ||
|
|
88e64b25c8 | ||
|
|
0ea2067e42 | ||
|
|
033febece6 | ||
|
|
12e6a6f94b | ||
|
|
31a3cbc327 |
15 changed files with 353 additions and 315 deletions
|
|
@ -62,6 +62,7 @@ body:
|
|||
options:
|
||||
- macOS
|
||||
- Windows
|
||||
- Linux
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
|
@ -80,6 +81,7 @@ body:
|
|||
Logs help us understand what went wrong behind the scenes. Here's how to find them:
|
||||
|
||||
**macOS:** Open Finder, press **Cmd+Shift+G**, and paste: `~/Library/Application Support/WoWBackup/logs`
|
||||
|
||||
**Windows:** Press **Win+R**, and paste: `%APPDATA%\WoWBackup\logs`
|
||||
|
||||
You can also open this folder from the app: go to **Settings** and click the **Open Logs** button at the bottom.
|
||||
|
|
|
|||
32
.github/workflows/release.yml
vendored
32
.github/workflows/release.yml
vendored
|
|
@ -154,7 +154,7 @@ jobs:
|
|||
#### Available Packages
|
||||
- **macOS**: \`.dmg\` installer (Apple Silicon & Intel)
|
||||
- **Windows**: \`.msi\` Windows Installer
|
||||
- **Linux**: \`.deb\` package (Debian / Ubuntu)
|
||||
- **Linux (Experimental)**: \`.deb\` package (Debian / Ubuntu)
|
||||
|
||||
---
|
||||
For detailed setup and installation notes, please refer to [INSTALL.md](https://git.asarius.site/rukira/wow-backup/src/tag/${RELEASE_TAG}/INSTALL.md)."
|
||||
|
|
@ -206,3 +206,33 @@ jobs:
|
|||
done
|
||||
|
||||
echo "Forgejo release published successfully."
|
||||
|
||||
- name: Update Homebrew Tap Cask
|
||||
env:
|
||||
FORGEJO_PAT: ${{ secrets.FORGEJO_PAT }}
|
||||
RELEASE_VERSION: ${{ needs.bump-version.outputs.version }}
|
||||
run: |
|
||||
DMG_FILE=$(find dist -name "*.dmg" | head -n 1)
|
||||
if [ -z "$DMG_FILE" ] || [ ! -f "$DMG_FILE" ]; then
|
||||
echo "::error::No DMG file found in dist/ to update Homebrew Cask."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SHA256=$(sha256sum "$DMG_FILE" | awk '{print $1}')
|
||||
echo "Calculated DMG SHA256: ${SHA256} for version ${RELEASE_VERSION}"
|
||||
|
||||
echo "Cloning homebrew-tap repository..."
|
||||
git clone "https://rukira:${FORGEJO_PAT}@git.asarius.site/rukira/homebrew-tap.git" tap-repo
|
||||
cd tap-repo
|
||||
|
||||
echo "Updating Casks/wow-backup.rb..."
|
||||
sed -i "s/version \".*\"/version \"${RELEASE_VERSION}\"/" Casks/wow-backup.rb
|
||||
sed -i "s/sha256 \".*\"/sha256 \"${SHA256}\"/" Casks/wow-backup.rb
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add Casks/wow-backup.rb
|
||||
git commit -m "chore(cask): update wow-backup to v${RELEASE_VERSION}" || echo "No changes to commit"
|
||||
git push origin main
|
||||
|
||||
echo "Homebrew tap updated successfully."
|
||||
|
|
|
|||
72
INSTALL.md
72
INSTALL.md
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Download
|
||||
|
||||
Download the appropriate installer for your platform from the **[latest release](https://git.asarius.site/rukira/wow-backup/releases)**:
|
||||
Download the appropriate installer for your platform from the **[latest release](https://git.asarius.site/rukira/wow-backup/releases/latest)**:
|
||||
|
||||
| Platform | Package Format | Installer File Pattern |
|
||||
|--------------------------|---|---|
|
||||
|
|
@ -10,23 +10,7 @@ Download the appropriate installer for your platform from the **[latest release]
|
|||
| **Windows** | Windows Installer (MSI) | `WoW Backup-<version>.msi` |
|
||||
| **Linux** (Experimental) | Debian Package (DEB) | `wow-backup_<version>_amd64.deb` |
|
||||
|
||||
---
|
||||
|
||||
## macOS
|
||||
|
||||
1. Download the `.dmg` file from the latest release.
|
||||
2. Double-click the `.dmg` file to mount the disk image.
|
||||
3. Drag **WoW Backup.app** into your `/Applications` folder.
|
||||
4. Eject the disk image.
|
||||
|
||||
### Unsigned Application / Gatekeeper Notice
|
||||
Because WoW Backup is distributed without Apple Developer ID code-signing notarization, macOS Gatekeeper may show a warning on first launch (*"WoW Backup cannot be opened because the developer cannot be verified"* or *"Apple could not verify that WoW Backup is free of malware"*).
|
||||
|
||||
To launch the app for the first time:
|
||||
1. Open **System Settings**
|
||||
2. Navigate to **Security & Privacy**.
|
||||
3. Click **Open Anyway** under **Allow apps downloaded from**.
|
||||
4. Restart WoW Backup.
|
||||
_Note: The Linux version is untested and experimental. Use at your own risk._
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -44,6 +28,58 @@ If Windows Defender SmartScreen flags the installer (*"Windows protected your PC
|
|||
|
||||
---
|
||||
|
||||
## macOS
|
||||
|
||||
### Option 1: Manual DMG Download
|
||||
|
||||
1. Download the `.dmg` file from the **[latest release](https://git.asarius.site/rukira/wow-backup/releases/latest)**.
|
||||
2. Double-click the `.dmg` file to mount the disk image.
|
||||
3. Drag **WoW Backup.app** into your `/Applications` folder.
|
||||
4. Eject the disk image.
|
||||
|
||||
#### Unsigned Application / Gatekeeper Notice
|
||||
Because WoW Backup is distributed without Apple Developer ID code-signing notarization, macOS Gatekeeper may show a warning on first launch (*"WoW Backup cannot be opened because the developer cannot be verified"* or *"Apple could not verify that WoW Backup is free of malware"*).
|
||||
|
||||
To launch the app:
|
||||
|
||||
- **Terminal (Fastest):** Run the following command to strip the quarantine attribute:
|
||||
```shell
|
||||
xattr -cr "/Applications/WoW Backup.app"
|
||||
```
|
||||
- **macOS System Settings:**
|
||||
1. Open **System Settings** → **Privacy & Security**.
|
||||
2. Scroll down to the **Security** section.
|
||||
3. Click **Open Anyway** next to the WoW Backup notice.
|
||||
4. Confirm and launch the app.
|
||||
|
||||
---
|
||||
|
||||
### Option 2: Install via [Homebrew](https://brew.sh/)
|
||||
|
||||
**Install:**
|
||||
1. Add the tap:
|
||||
```shell
|
||||
brew tap rukira/tap https://git.asarius.site/rukira/homebrew-tap.git
|
||||
```
|
||||
|
||||
2. Install WoW Backup:
|
||||
```shell
|
||||
brew install --cask wow-backup
|
||||
```
|
||||
|
||||
**Update:**
|
||||
```shell
|
||||
brew update
|
||||
brew upgrade --cask wow-backup
|
||||
```
|
||||
|
||||
**Uninstall:**
|
||||
```shell
|
||||
brew uninstall --cask --zap wow-backup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Linux (Experimental)
|
||||
|
||||
1. Download the `.deb` package from the latest release.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
# WoW Backup
|
||||
|
||||
A lightweight, native-feeling desktop application to automatically backup World of Warcraft configuration data (WTF and Interface directories).
|
||||
|
||||
World of Warcraft stores all UI configurations, macros, keybindings, and addon data in the `WTF/` and `Interface/` folders. Losing this data due to game corruption, accidental deletion, or addon errors can mean losing years of customized setups. **WoW Backup** runs discreetly in the system tray, and automatically performs scheduled, timestamped backups (optionally compressed as ZIP archives).
|
||||

|
||||
|
||||
## Installation & Download
|
||||
|
||||
|
|
@ -75,4 +71,4 @@ The app uses a configuration file to store user preferences. This file and runti
|
|||
|
||||
## License
|
||||
|
||||
This project is released into the public domain. See the [LICENSE](LICENSE) file or [unlicense.org](https://unlicense.org/) for details.
|
||||
This project is released into the public domain. See the [UNLICENSE](UNLICENSE) file or [unlicense.org](https://unlicense.org/) for details.
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ kotlin {
|
|||
|
||||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
implementation(compose.runtime)
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.material3)
|
||||
implementation(compose.ui)
|
||||
implementation(compose.components.resources)
|
||||
implementation(compose.components.uiToolingPreview)
|
||||
implementation(libs.compose.runtime)
|
||||
implementation(libs.compose.foundation)
|
||||
implementation(libs.compose.material3)
|
||||
implementation(libs.compose.ui)
|
||||
implementation(libs.compose.components.resources)
|
||||
implementation(libs.compose.components.uiToolingPreview)
|
||||
implementation(libs.androidx.lifecycle.viewmodelCompose)
|
||||
implementation(libs.androidx.lifecycle.runtimeCompose)
|
||||
}
|
||||
|
|
@ -42,7 +42,8 @@ val appVersion = providers.gradleProperty("appVersion").orNull?.takeIf { it.isNo
|
|||
|
||||
val generatedSrcDir = layout.buildDirectory.dir("generated/src/jvmMain/kotlin")
|
||||
|
||||
val generateBuildConfig by tasks.registering {
|
||||
val generateBuildConfig = tasks.register("generateBuildConfig") {
|
||||
description = "Generates BuildConfig.kt"
|
||||
val outputDir = generatedSrcDir
|
||||
val version = appVersion
|
||||
inputs.property("version", version)
|
||||
|
|
@ -70,18 +71,24 @@ compose.desktop {
|
|||
application {
|
||||
mainClass = "com.rukira.wowbackup.MainKt"
|
||||
|
||||
jvmArgs("-Dapple.awt.enableTemplateImages=true")
|
||||
jvmArgs("-Dapple.awt.enableTemplateImages=true", "-Dapple.awt.UIElement=true")
|
||||
|
||||
nativeDistributions {
|
||||
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
||||
packageName = "WoW Backup"
|
||||
packageVersion = appVersion
|
||||
|
||||
modules("java.naming", "java.sql", "java.instrument", "jdk.unsupported")
|
||||
modules("java.naming", "java.sql", "java.instrument", "jdk.unsupported", "java.net.http")
|
||||
|
||||
macOS {
|
||||
bundleID = "com.rukira.wowbackup"
|
||||
iconFile.set(project.file("src/jvmMain/resources/icon.icns"))
|
||||
infoPlist {
|
||||
extraKeysRawXml = """
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
|
||||
windows {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ import java.awt.GraphicsEnvironment
|
|||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
fun main() {
|
||||
if (Platform.current == OS.Mac) {
|
||||
System.setProperty("apple.awt.UIElement", "true")
|
||||
}
|
||||
LoggingSetup.init()
|
||||
logger.info { "WoW Backup starting" }
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,12 @@ fun ConfigScreen(
|
|||
var showForceBackupDialog by remember { mutableStateOf(false) }
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
Column(modifier = Modifier.fillMaxSize()) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
|
@ -263,14 +268,29 @@ fun ConfigScreen(
|
|||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
|
||||
// === Footer ===
|
||||
Spacer(Modifier.height(8.dp))
|
||||
VerticalScrollbar(
|
||||
modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
|
||||
adapter = rememberScrollbarAdapter(scrollState),
|
||||
style = ScrollbarStyle(
|
||||
minimalHeight = 48.dp,
|
||||
thickness = 8.dp,
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
hoverDurationMillis = 300,
|
||||
unhoverColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.3f),
|
||||
hoverColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// === Sticky Footer ===
|
||||
HorizontalDivider()
|
||||
Spacer(Modifier.height(8.dp))
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 16.dp),
|
||||
horizontalArrangement = Arrangement.End,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
|
|
@ -303,20 +323,6 @@ fun ConfigScreen(
|
|||
}
|
||||
}
|
||||
|
||||
VerticalScrollbar(
|
||||
modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
|
||||
adapter = rememberScrollbarAdapter(scrollState),
|
||||
style = ScrollbarStyle(
|
||||
minimalHeight = 48.dp,
|
||||
thickness = 8.dp,
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
hoverDurationMillis = 300,
|
||||
unhoverColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.3f),
|
||||
hoverColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// Force backup confirmation dialog
|
||||
if (showForceBackupDialog) {
|
||||
ConfirmationDialog(
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ fun WoWBackupTheme(
|
|||
|
||||
DynamicMaterialTheme(
|
||||
seedColor = accentColor.seedColor,
|
||||
useDarkTheme = useDarkTheme,
|
||||
isDark = useDarkTheme,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,18 +84,31 @@ Strip all template code. Route to placeholder screens based on `currentScreen`:
|
|||
### Step 5: Auto-show config if not configured
|
||||
In `main.kt`, on startup check `ConfigManager.isConfigured`. If false, set `currentScreen = Screen.CONFIG` and `isWindowVisible = true`.
|
||||
|
||||
### Step 6: macOS JVM args
|
||||
### Step 6: macOS JVM args and Dock hiding (LSUIElement)
|
||||
**Files to modify:**
|
||||
- `composeApp/build.gradle.kts` — add to desktop application config:
|
||||
|
||||
```kotlin
|
||||
compose.desktop {
|
||||
application {
|
||||
jvmArgs("-Dapple.awt.enableTemplateImages=true")
|
||||
jvmArgs("-Dapple.awt.enableTemplateImages=true", "-Dapple.awt.UIElement=true")
|
||||
|
||||
nativeDistributions {
|
||||
macOS {
|
||||
infoPlist {
|
||||
extraKeysRawXml = """
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Also set `System.setProperty("apple.awt.UIElement", "true")` in `main.kt` for macOS so that the dock icon is suppressed during development runs.
|
||||
|
||||
## Verification
|
||||
1. `./gradlew composeApp:run` — app launches with tray icon visible
|
||||
2. Tray icon shows context menu with Status, Settings, Quit
|
||||
|
|
|
|||
|
|
@ -4,75 +4,13 @@ This document outlines the current state of the project, remaining core features
|
|||
|
||||
---
|
||||
|
||||
## 1. Immediate Priority: Feature 5 (Restore System)
|
||||
## Immediate Priority: Feature 5 (Restore System)
|
||||
|
||||
The core backup and scheduling pipeline is complete, but the restoration flow is currently a stub placeholder. Implementing Feature 5 is the final step to complete the original functional scope of `docs/masterplan.md`.
|
||||
|
||||
### Tasks:
|
||||
1. **Restore Engine (`RestoreEngine.kt`)**
|
||||
- Implement `restoreBackup(entry: BackupEntry, targetDir: File): RestoreResult`.
|
||||
- Support restoring from both timestamped directory structures and `.zip` archives (extracting using `ZipInputStream`).
|
||||
- Clean/delete existing target folders (`WTF` and/or `Interface`) safely before copy/extraction.
|
||||
- Implement live progress reporting (`RestoreProgress` with total files, completed count, current file name).
|
||||
- Ensure full cancellation support via Kotlin Coroutines.
|
||||
2. **Safety & Validation Mechanics**
|
||||
- Warn or guard if World of Warcraft is currently running during restoration.
|
||||
- Verify backup integrity and destination disk space before starting destructive deletion.
|
||||
- Create an automatic temporary safety snapshot of current `WTF`/`Interface` folders prior to overwrite.
|
||||
3. **Restore ViewModel (`RestoreViewModel.kt`)**
|
||||
- Expose `RestoreUiState` combining available backups list, selected entry, progress, and confirmation states.
|
||||
- Manage restore lifecycle (start, cancel, dismiss, error handling).
|
||||
4. **Restore Screen UI (`RestoreScreen.kt`)**
|
||||
- Replace placeholder with scrollable list of existing backups displaying date/time, archive size, and format badge.
|
||||
- Material 3 confirmation dialog detailing destructive overwrite.
|
||||
- Progress overlay with `LinearProgressIndicator`, active file, and cancellation button.
|
||||
- Empty state when no backups are present.
|
||||
5. **App Wiring**
|
||||
- Connect `Screen.RESTORE` in `App.kt` to `RestoreScreen`.
|
||||
- Enable the "Restore" button on `StatusScreen.kt`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Testing Infrastructure & Automated Test Suite
|
||||
|
||||
Currently, the project contains no automated test suite (`src/jvmTest` is empty). Adding tests will prevent regressions during future maintenance.
|
||||
|
||||
### Test Targets:
|
||||
1. **`BackupHistoryTest`**:
|
||||
- Timestamp parsing across formats and edge cases.
|
||||
- Backup listing and correct descending sort order.
|
||||
- Retention policy pruning (ensuring only oldest backups exceeding count are deleted).
|
||||
- Metrics computation for directory trees and ZIP files.
|
||||
2. **`BackupEngineTest` & `RestoreEngineTest`**:
|
||||
- File copy accuracy, recursive folder preservation, and attribute retention.
|
||||
- ZIP compression and decompression fidelity.
|
||||
- Cancellation responsiveness and cleanup of partial writes.
|
||||
3. **`ConfigManagerTest`**:
|
||||
- JSON serialization / deserialization defaults and edge cases.
|
||||
- Thread-safe updates and reactive `StateFlow` emissions.
|
||||
4. **`WoWLocationsTest`**:
|
||||
- Install directory heuristics and resolution from root `World of Warcraft` to `_retail_` or `_classic_`.
|
||||
- Missing folder detection and permission warnings.
|
||||
|
||||
---
|
||||
|
||||
## 3. Build Automation & Release Pipeline (Completed)
|
||||
|
||||
Automated multi-platform packaging and release pipeline implemented via GitHub Actions (`.github/workflows/release.yml`) and documented in `INSTALL.md` and `docs/plans/feature-6-release-pipeline.md`.
|
||||
|
||||
### Implemented:
|
||||
1. **GitHub Actions Release Pipeline**
|
||||
- Automated semantic patch version computation and git tagging on push to `main` and `workflow_dispatch`.
|
||||
- Matrix builds on macOS (`macos-latest`), Windows (`windows-latest`), and Linux (`ubuntu-latest`).
|
||||
2. **Automated Distribution Packaging & GitHub Releases**
|
||||
- Automated artifact generation and release publishing for `.dmg` (macOS), `.msi` (Windows), and `.deb` (Linux).
|
||||
- Dynamic version injection via `-PappVersion` in `composeApp/build.gradle.kts`.
|
||||
3. **Installation Documentation**
|
||||
- Detailed `INSTALL.md` guide covering installation and security prompts (Gatekeeper / SmartScreen) across all platforms.
|
||||
|
||||
---
|
||||
|
||||
## 4. Future Enhancements (Post-v1.0)
|
||||
## Future Enhancements (Post-v1.0)
|
||||
|
||||
1. **Multi-Flavour & Account Profile Support**
|
||||
- Support backing up multiple game versions simultaneously (`_retail_`, `_classic_`, `_classic_era_`, `_ptr_`).
|
||||
|
|
|
|||
BIN
docs/screenshots/hero.png
Normal file
BIN
docs/screenshots/hero.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 259 KiB |
BIN
docs/screenshots/wow-backup-hero.xcf
Normal file
BIN
docs/screenshots/wow-backup-hero.xcf
Normal file
Binary file not shown.
|
|
@ -1,18 +1,25 @@
|
|||
[versions]
|
||||
androidx-lifecycle = "2.10.0-alpha08"
|
||||
composeMultiplatform = "1.11.0-alpha03"
|
||||
androidx-lifecycle = "2.11.0"
|
||||
composeMaterial3 = "1.9.0"
|
||||
composeMultiplatform = "1.11.1"
|
||||
kotlin = "2.2.21"
|
||||
kotlinx-coroutines = "1.10.2"
|
||||
kotlinx-datetime = "0.6.2"
|
||||
kotlinx-serialization = "1.10.0"
|
||||
kotlinx-coroutines = "1.11.0"
|
||||
kotlinx-datetime = "0.8.0"
|
||||
kotlinx-serialization = "1.11.0"
|
||||
cardiologist = "0.8.0"
|
||||
kotlin-logging = "7.0.3"
|
||||
logback = "1.5.18"
|
||||
materialKolor = "2.0.0"
|
||||
kotlin-logging = "8.0.4"
|
||||
logback = "1.5.38"
|
||||
materialKolor = "4.0.5"
|
||||
|
||||
[libraries]
|
||||
androidx-lifecycle-viewmodelCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
|
||||
androidx-lifecycle-runtimeCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
|
||||
compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "composeMultiplatform" }
|
||||
compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "composeMultiplatform" }
|
||||
compose-material3 = { module = "org.jetbrains.compose.material3:material3", version.ref = "composeMaterial3" }
|
||||
compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "composeMultiplatform" }
|
||||
compose-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "composeMultiplatform" }
|
||||
compose-components-uiToolingPreview = { module = "org.jetbrains.compose.components:components-ui-tooling-preview", version.ref = "composeMultiplatform" }
|
||||
kotlinx-coroutinesSwing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" }
|
||||
kotlinx-coroutinesTest = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
|
||||
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" }
|
||||
|
|
|
|||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -1,6 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue