1. Create a project
You can directly create a project using the GitHub template, which integrates the following functions out of the box:
β
Internationalization (i18n) using vue-i18n
π Automatic light/dark theme support with manual override
ποΈ SQLite database integration with CRUD operations
β¨οΈ Keyboard shortcut (hotkey) support for efficient interaction and easy extension
βοΈ Settings panel and hotkey configuration demo
π‘ Built with Wails v3, Vue 3, and TypeScript
Here are two ways to create:
#1γCreate a project directly through the GitHub template
wails3 init -n myProject -t https://github.com/JinGongX/SuiDemo
#2γClone the project to the local => Create the project
git clone https://github.com/JinGongX/SuiDemo
wails3 init -n "Your Project Name" -t ./"suidemo local directory"
II. Project Development
The basic functions in the original template are ready to use out of the box, and basically, only the front-end needs to be continuously developed
- Write a prompt display page
/* /pages/Tips/Index.vue*/
<script setup lang="ts">
import { ref,onMounted,onUnmounted } from'vue'
import { InsTips } from'../../../bindings/changeme/services/suistore'
import{HideTipsWindow} from'../../../bindings/changeme/appservice'
import { applyTheme } from'../../utils/ThemeManager'
const input = ref('')
const sendMessage = () => {
if (!input.value.trim()) return
const now = Math.floor(Date.now() / 1000)
const expireAt = parseTime(input.value) || (now + 30 * 60)
InsTips(detectType(input.value), input.value, expireAt)
input.value = ''
HideTipsWindow()//Hide
}
// Monitor the Esc key to close the panel
const onKeydown = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
input.value = ''
HideTipsWindow()
}
}
onMounted(() => {
window.addEventListener('keydown', onKeydown)
})
onUnmounted(() => {
window.removeEventListener('keydown', onKeydown)
})
//--- A simple function for identifying type and time can be subsequently integrated into a large model ---
type PromptType = 'security' | 'device' | 'life' | 'work'|'system' |'default'
function detectType(text: string): PromptType {
if (/password|security|verify/.test(text)) return'security'
if (/backup|storage|photo|computer/.test(text)) return'device'
if (/food|cook|life/.test(text)) return'life'
if (/meeting|task|work/.test(text)) return'work'
return'default'
}
function parseTime(text: string): number | undefined {
const m = text.match(/(\d+)\s*(ει|ε|min|m)/)
if (m) returnDate.now() + Number(m[1]) * 60 * 1000
returnundefined
}
//Adjust the style on the configuration page and synchronize it to the child window
const bc = new BroadcastChannel('theme')
bc.onmessage = (e) => {
applyTheme(e.data)
}
</script>
<template>
<div
class="fixed inset-0 flex items-center justify-center bg-black/20 backdrop-blur-sm dark:bg-gray-400/20"
>
<div class="w-[420px] rounded-1xl bg-white/90 dark:bg-gray-500/90 dark:text-white backdrop-blur-md shadow-[0_16px_40px_rgba(0,0,0,0.18)] px-5 py-4"
>
<div class="mb-3 text-sm text-neutral-500 dark:text-white">
Prompt: Enter a reminder for yourself
</div>
<textarea
v-model="input" @keydown.enter.prevent="sendMessage"
rows="2"
placeholder="For example: Remind me to back up my photos in 30 minutes"
class="w-full resize-none rounded-xl border border-neutral-200 bg-neutral-50 dark:bg-gray-100 px-4 py-3 text-sm text-neutral-900 placeholder:text-neutral-400 focus:border-neutral-300 focus:outline-none"
/>
<div class="mt-3 flex items-center justify-between text-xs text-neutral-400 dark:text-white">
<div>Enter confirm Β· Esc cancel</div>
<div>Automatic type recognition</div>
</div>
</div>
</div>
</template>
III. The complete effect is roughly as follows:


Top comments (0)