mirror of
https://github.com/AventurasTeam/Aventuras.git
synced 2026-04-28 03:40:11 +00:00
Current
This commit is contained in:
parent
d088915be5
commit
3e9fd2b864
5 changed files with 239 additions and 11 deletions
155
.github/workflows/release.yml
vendored
Normal file
155
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version tag (e.g., v0.1.0)'
|
||||
required: true
|
||||
default: 'v0.1.0'
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build-desktop:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- platform: ubuntu-22.04
|
||||
target: x86_64-unknown-linux-gnu
|
||||
artifact_name: linux
|
||||
- platform: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
artifact_name: windows
|
||||
- platform: macos-latest
|
||||
target: x86_64-apple-darwin
|
||||
artifact_name: macos-intel
|
||||
- platform: macos-latest
|
||||
target: aarch64-apple-darwin
|
||||
artifact_name: macos-arm
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-action@stable
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- name: Install Linux dependencies
|
||||
if: matrix.platform == 'ubuntu-22.04'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build Tauri app
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tagName: ${{ github.ref_name }}
|
||||
releaseName: 'Aventura ${{ github.ref_name }}'
|
||||
releaseBody: 'See the assets to download and install this version.'
|
||||
releaseDraft: true
|
||||
prerelease: false
|
||||
args: --target ${{ matrix.target }}
|
||||
|
||||
build-android:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-action@stable
|
||||
with:
|
||||
targets: aarch64-linux-android,armv7-linux-androideabi,i686-linux-android,x86_64-linux-android
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
|
||||
- name: Setup Android SDK
|
||||
uses: android-actions/setup-android@v3
|
||||
|
||||
- name: Setup Android NDK
|
||||
uses: nttld/setup-ndk@v1
|
||||
id: setup-ndk
|
||||
with:
|
||||
ndk-version: r27
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Install Tauri CLI
|
||||
run: npm install -g @tauri-apps/cli
|
||||
|
||||
- name: Initialize Android
|
||||
run: tauri android init
|
||||
|
||||
- name: Build Android APK
|
||||
env:
|
||||
NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
run: tauri android build
|
||||
|
||||
- name: Decode keystore
|
||||
env:
|
||||
KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
||||
run: |
|
||||
echo "$KEYSTORE_BASE64" | base64 -d > aventura-release.keystore
|
||||
|
||||
- name: Sign APK
|
||||
env:
|
||||
KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||
KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
||||
run: |
|
||||
$ANDROID_HOME/build-tools/34.0.0/apksigner sign \
|
||||
--ks aventura-release.keystore \
|
||||
--ks-key-alias "$KEY_ALIAS" \
|
||||
--ks-pass pass:"$KEYSTORE_PASSWORD" \
|
||||
--key-pass pass:"$KEY_PASSWORD" \
|
||||
--out aventura-release.apk \
|
||||
src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release-unsigned.apk
|
||||
|
||||
- name: Upload Android APK
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: android-apk
|
||||
path: aventura-release.apk
|
||||
|
||||
- name: Upload to Release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
draft: true
|
||||
files: aventura-release.apk
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -18,6 +18,7 @@
|
|||
*.keystore
|
||||
*.jks
|
||||
keystore.properties
|
||||
keystore-base64.txt
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Dependencies
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
<script lang="ts">
|
||||
import { story } from '$lib/stores/story.svelte';
|
||||
import { Plus, MapPin, Eye, Navigation } from 'lucide-svelte';
|
||||
import { Plus, MapPin, Eye, EyeOff, Navigation, Trash2 } from 'lucide-svelte';
|
||||
|
||||
let showAddForm = $state(false);
|
||||
let newName = $state('');
|
||||
let newDescription = $state('');
|
||||
let confirmingDeleteId = $state<string | null>(null);
|
||||
|
||||
async function addLocation() {
|
||||
if (!newName.trim()) return;
|
||||
|
|
@ -18,6 +19,15 @@
|
|||
async function goToLocation(locationId: string) {
|
||||
await story.setCurrentLocation(locationId);
|
||||
}
|
||||
|
||||
async function toggleVisited(locationId: string) {
|
||||
await story.toggleLocationVisited(locationId);
|
||||
}
|
||||
|
||||
async function deleteLocation(locationId: string) {
|
||||
await story.deleteLocation(locationId);
|
||||
confirmingDeleteId = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="space-y-3">
|
||||
|
|
@ -86,22 +96,52 @@
|
|||
</div>
|
||||
<div>
|
||||
<span class="font-medium text-surface-100">{location.name}</span>
|
||||
{#if location.visited}
|
||||
<span class="ml-2 text-xs text-surface-500">
|
||||
<button
|
||||
class="ml-2 text-xs transition-colors {location.visited ? 'text-surface-500 hover:text-surface-300' : 'text-surface-600 hover:text-surface-400'}"
|
||||
onclick={() => toggleVisited(location.id)}
|
||||
title={location.visited ? 'Click to mark as unvisited' : 'Click to mark as visited'}
|
||||
>
|
||||
{#if location.visited}
|
||||
<Eye class="inline h-3 w-3" /> visited
|
||||
</span>
|
||||
{/if}
|
||||
{:else}
|
||||
<EyeOff class="inline h-3 w-3" /> unvisited
|
||||
{/if}
|
||||
</button>
|
||||
{#if location.description}
|
||||
<p class="mt-1 text-sm text-surface-400">{location.description}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="btn-ghost rounded px-2 py-1 text-xs"
|
||||
onclick={() => goToLocation(location.id)}
|
||||
>
|
||||
Go
|
||||
</button>
|
||||
<div class="flex items-center gap-1">
|
||||
{#if confirmingDeleteId === location.id}
|
||||
<button
|
||||
class="btn-ghost rounded px-2 py-1 text-xs text-red-400 hover:bg-red-500/20"
|
||||
onclick={() => deleteLocation(location.id)}
|
||||
>
|
||||
Confirm
|
||||
</button>
|
||||
<button
|
||||
class="btn-ghost rounded px-2 py-1 text-xs"
|
||||
onclick={() => confirmingDeleteId = null}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
{:else}
|
||||
<button
|
||||
class="btn-ghost rounded px-2 py-1 text-xs"
|
||||
onclick={() => goToLocation(location.id)}
|
||||
>
|
||||
Go
|
||||
</button>
|
||||
<button
|
||||
class="btn-ghost rounded p-1 text-surface-500 hover:text-red-400"
|
||||
onclick={() => confirmingDeleteId = location.id}
|
||||
title="Delete location"
|
||||
>
|
||||
<Trash2 class="h-3.5 w-3.5" />
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
|
|
|
|||
|
|
@ -298,6 +298,11 @@ class DatabaseService {
|
|||
await db.execute(`UPDATE locations SET ${setClauses.join(', ')} WHERE id = ?`, values);
|
||||
}
|
||||
|
||||
async deleteLocation(id: string): Promise<void> {
|
||||
const db = await this.getDb();
|
||||
await db.execute('DELETE FROM locations WHERE id = ?', [id]);
|
||||
}
|
||||
|
||||
// Item operations
|
||||
async getItems(storyId: string): Promise<Item[]> {
|
||||
const db = await this.getDb();
|
||||
|
|
|
|||
|
|
@ -561,6 +561,33 @@ class StoryStore {
|
|||
}));
|
||||
}
|
||||
|
||||
// Toggle location visited status
|
||||
async toggleLocationVisited(locationId: string): Promise<void> {
|
||||
if (!this.currentStory) throw new Error('No story loaded');
|
||||
|
||||
const location = this.locations.find(l => l.id === locationId);
|
||||
if (!location) throw new Error('Location not found');
|
||||
|
||||
const newVisited = !location.visited;
|
||||
await database.updateLocation(locationId, { visited: newVisited });
|
||||
this.locations = this.locations.map(l =>
|
||||
l.id === locationId ? { ...l, visited: newVisited } : l
|
||||
);
|
||||
log('Location visited toggled:', location.name, newVisited);
|
||||
}
|
||||
|
||||
// Delete a location
|
||||
async deleteLocation(locationId: string): Promise<void> {
|
||||
if (!this.currentStory) throw new Error('No story loaded');
|
||||
|
||||
const location = this.locations.find(l => l.id === locationId);
|
||||
if (!location) throw new Error('Location not found');
|
||||
|
||||
await database.deleteLocation(locationId);
|
||||
this.locations = this.locations.filter(l => l.id !== locationId);
|
||||
log('Location deleted:', location.name);
|
||||
}
|
||||
|
||||
// Add an item to inventory
|
||||
async addItem(name: string, description?: string, quantity = 1): Promise<Item> {
|
||||
if (!this.currentStory) throw new Error('No story loaded');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue