This commit is contained in:
Leon Liu 2025-01-03 09:48:27 +09:00
parent 4ed7c8062a
commit 20dc07b0e3
30 changed files with 5069 additions and 59 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -13,6 +13,7 @@
"format": "prettier --write src/"
},
"dependencies": {
"@tauri-apps/plugin-fs": "~2",
"file-saver": "^2.0.5",
"fp-ts": "^2.16.9",
"pinia": "^2.3.0",
@ -24,6 +25,7 @@
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.15",
"@tauri-apps/cli": "^2.2.0",
"@tsconfig/node22": "^22.0.0",
"@types/file-saver": "^2.0.7",
"@types/node": "^22.10.2",

4
src-tauri/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Generated by Cargo
# will have compiled files and executables
/target/
/gen/schemas

4834
src-tauri/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

26
src-tauri/Cargo.toml Normal file
View File

@ -0,0 +1,26 @@
[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
edition = "2021"
rust-version = "1.77.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2.0.3", features = [] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
log = "0.4"
tauri = { version = "2.2.0", features = [] }
tauri-plugin-log = "2.0.0-rc"
tauri-plugin-fs = "2"

3
src-tauri/build.rs Normal file
View File

@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}

View File

@ -0,0 +1,16 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "enables the default permissions",
"windows": [
"main"
],
"permissions": [
"core:default",
"fs:default",
{
"identifier": "fs:allow-write-text-file",
"allow": [{ "path": "$DOCUMENT/My Games/Path of Exile 2/*" }]
}
]
}

BIN
src-tauri/icons/128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
src-tauri/icons/32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
src-tauri/icons/icon.icns Normal file

Binary file not shown.

BIN
src-tauri/icons/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
src-tauri/icons/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

17
src-tauri/src/lib.rs Normal file
View File

@ -0,0 +1,17 @@
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_fs::init())
.setup(|app| {
if cfg!(debug_assertions) {
app.handle().plugin(
tauri_plugin_log::Builder::default()
.level(log::LevelFilter::Info)
.build(),
)?;
}
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

6
src-tauri/src/main.rs Normal file
View File

@ -0,0 +1,6 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
app_lib::run();
}

37
src-tauri/tauri.conf.json Normal file
View File

@ -0,0 +1,37 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "poe2-loot-filter-vue",
"version": "0.1.0",
"identifier": "com.tauri.dev",
"build": {
"frontendDist": "../dist",
"devUrl": "http://localhost:5173",
"beforeDevCommand": "bun dev",
"beforeBuildCommand": "bun build"
},
"app": {
"windows": [
{
"title": "poe2-loot-filter-vue",
"width": 800,
"height": 600,
"resizable": true,
"fullscreen": false
}
],
"security": {
"csp": null
}
},
"bundle": {
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
}

View File

@ -10,6 +10,7 @@ import { pipe } from 'fp-ts/function'
import FileSaver from 'file-saver'
import { generateFilterText, type Filter, type FilterConfig, type FilterNode } from './models'
import { filterToTreeNode, treeNodeToFilter } from './services/filter'
import { exists, BaseDirectory, writeTextFile } from '@tauri-apps/plugin-fs';
const darkMode = ref(document.documentElement.classList.contains('dark'))
@ -57,15 +58,23 @@ function exportFilter() {
function download() {
var blob = new Blob([previewText.value], { type: "text/plain;charset=utf-8" });
FileSaver.saveAs(blob, "poe2.filter")
FileSaver.saveAs(blob, "Clearfell Default.filter")
}
const exportDialogVisible = ref(false);
function save() {
async function save(toastOnComplete?: boolean) {
if (nodes.value) {
const filters = toRaw(nodes.value).map(treeNodeToFilter)
localStorage.setItem("filters", JSON.stringify(filters))
let text = generateFilterText(filters)
await writeTextFile('My Games/Path of Exile 2/Clearfell Default.filter', text, {
baseDir: BaseDirectory.Document,
});
if (toastOnComplete) {
toast.add({ severity: 'success', summary: 'Success', detail: 'Content Saved', life: 3000 });
}
}
}
@ -80,12 +89,11 @@ setInterval(save, 5000)
<article class="prose dark:prose-invert p-4">
<h1>Path of Exile 2 Loot Filter Config</h1>
</article><Button :icon @click="darkMode = !darkMode" severity="secondary" variant="outlined" rounded />
<Button icon="pi pi-save" label="Save" severity="secondary" variant="outlined" rounded
@click="save(); toast.add({ severity: 'success', summary: 'Success', detail: 'Content Saved', life: 3000 });" />
<Button icon="pi pi-save" label="Save" severity="secondary" variant="outlined" rounded @click="save(true)" />
<Button icon="pi pi-file-export" label="Export" severity="primary" @click="exportFilter" />
<Dialog v-model:visible="exportDialogVisible" modal header="Preview Filter Text">
<template #default>
<ScrollPanel class="h-[50vh]">
<ScrollPanel class="h-[50vh] w-[50vw]">
<pre>{{ previewText }}</pre>
</ScrollPanel>
</template>

View File

@ -4,6 +4,7 @@ import { computed, ref, watchEffect } from 'vue'
import { Button, ColorPicker, ScrollPanel, Tabs, Tab, TabPanels, TabList, TabPanel, ToggleButton, InputText, InputNumber, Select, ToggleSwitch, MultiSelect } from 'primevue'
import { useConfirm } from "primevue/useconfirm";
import { useToast } from "primevue/usetoast";
import { CLASSES, COLORS, BASE_TYPES, RARITIES, SHAPES, OPERATORS } from '@/models/settings';
const confirm = useConfirm();
const toast = useToast();
@ -36,55 +37,7 @@ const props = defineProps<{
node: FilterNode,
onDelete: () => void
}>()
const OPERATORS = ['=', '==', '!=', '<', '<=', '>', '>='];
const COLORS = [
'Red',
'Green',
'Blue',
'Brown',
'White',
'Yellow',
'Cyan',
'Grey',
'Orange',
'Pink',
'Purple'
];
const SHAPES = [
'Circle',
'Diamond',
'Hexagon',
'Square',
'Star',
'Triangle',
'Cross',
'Moon',
'Raindrop',
'Kite',
'Pentagon',
'UpsideDownHouse'
];
const RARITIES = ['Normal', 'Magic', 'Rare', 'Unique'];
const CLASSES = [
'Currency', 'Stackable Currency', 'Jewel', 'Abyss Jewel', 'Divination Card',
'Gem', 'Flask', 'Map', 'Map Fragment', 'Fishing Rods', 'Amulet', 'Ring',
'Claw', 'Dagger', 'Wand', 'One Hand Sword', 'Thrusting One Hand Sword',
'One Hand Axe', 'One Hand Mace', 'Sceptre', 'Rune Dagger', 'Bow', 'Staff',
'Two Hand Sword', 'Two Hand Axe', 'Two Hand Mace', 'Warstaff', 'Body Armour',
'Boots', 'Gloves', 'Helmet', 'Shield', 'Quiver'
];
const BASE_TYPES = [
'Exalted Orb', 'Mirror of Kalandra', 'Eternal Orb', 'Divine Orb',
'Orb of Annulment', 'Chaos Orb', 'Vaal Orb', 'Regal Orb', 'Orb of Alchemy',
'Orb of Fusing', 'Blessed Orb', 'Cartographer\'s Chisel', 'Orb of Scouring',
'Jeweller\'s Orb', 'Chromatic Orb', 'Orb of Chance', 'Orb of Alteration',
'Orb of Transmutation', 'Scroll of Wisdom', 'Portal Scroll'
];
const filter = computed(() => props.node.data)

88
src/models/settings.ts Normal file
View File

@ -0,0 +1,88 @@
export const OPERATORS = ['=', '==', '!=', '<', '<=', '>', '>=']
export const COLORS = [
'Red',
'Green',
'Blue',
'Brown',
'White',
'Yellow',
'Cyan',
'Grey',
'Orange',
'Pink',
'Purple',
]
export const SHAPES = [
'Circle',
'Diamond',
'Hexagon',
'Square',
'Star',
'Triangle',
'Cross',
'Moon',
'Raindrop',
'Kite',
'Pentagon',
'UpsideDownHouse',
]
export const RARITIES = ['Normal', 'Magic', 'Rare', 'Unique']
export const CLASSES = [
'Currency',
'Stackable Currency',
'Jewel',
'Abyss Jewel',
'Divination Card',
'Gem',
'Flask',
'Map',
'Map Fragment',
'Fishing Rods',
'Amulet',
'Ring',
'Claw',
'Dagger',
'Wand',
'One Hand Sword',
'One Hand Axe',
'One Hand Mace',
'Sceptre',
'Bow',
'Staff',
'Two Hand Sword',
'Two Hand Axe',
'Two Hand Mace',
'Body Armour',
'Boots',
'Gloves',
'Helmet',
'Shield',
'Quiver',
]
export const BASE_TYPES = [
'Exalted Orb',
'Mirror of Kalandra',
'Eternal Orb',
'Divine Orb',
'Orb of Annulment',
'Chaos Orb',
'Vaal Orb',
'Regal Orb',
'Orb of Alchemy',
'Orb of Fusing',
'Blessed Orb',
"Cartographer's Chisel",
'Orb of Scouring',
"Jeweller's Orb",
'Chromatic Orb',
'Orb of Chance',
'Orb of Alteration',
'Orb of Transmutation',
'Scroll of Wisdom',
'Portal Scroll',
]

View File

@ -3,16 +3,32 @@ import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
const host = process.env.TAURI_DEV_HOST
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
vueDevTools(),
],
// prevent vite from obscuring rust errors
clearScreen: false,
server: {
// Tauri expects a fixed port, fail if that port is not available
strictPort: true,
// if the host Tauri is expecting is set, use it
host: host || false,
port: 5173,
},
// Env variables starting with the item of `envPrefix` will be exposed in tauri's source code through `import.meta.env`.
envPrefix: ['VITE_', 'TAURI_ENV_*'],
build: {
// Tauri uses Chromium on Windows and WebKit on macOS and Linux
target: process.env.TAURI_ENV_PLATFORM == 'windows' ? 'chrome105' : 'safari13',
// don't minify for debug builds
minify: !process.env.TAURI_ENV_DEBUG ? 'esbuild' : false,
// produce sourcemaps for debug builds
sourcemap: !!process.env.TAURI_ENV_DEBUG,
},
plugins: [vue(), vueDevTools()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
})