Merge branch 'develop'

This commit is contained in:
Nicola Spadari
2025-03-10 14:13:44 +01:00
33 changed files with 2707 additions and 1496 deletions

View File

@@ -28,7 +28,7 @@ jobs:
- name: setup node
uses: actions/setup-node@v4
with:
node-version: 23.5.0
node-version: 23.8.0
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
@@ -46,7 +46,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9.15.4
version: 10.6.2
- name: install frontend dependencies
run: pnpm install

2
.nuxtignore Normal file
View File

@@ -0,0 +1,2 @@
./*
!./app/**

2
.nvmrc
View File

@@ -1 +1 @@
23.5.0
23.8.0

View File

@@ -23,6 +23,8 @@ Build super fast desktop applications!
<p align="center">Powered by Nuxt 3</p>
Check more screenshots at [preview](https://github.com/NicolaSpadari/nuxtor/preview.md)
<br />
## Technologies run-down

View File

@@ -7,6 +7,24 @@ export default defineAppConfig({
nuxtSite: "https://nuxt.com",
nuxtUiSite: "https://ui3.nuxt.dev"
},
pageCategories: {
system: {
label: "System",
icon: "lucide:square-terminal"
},
storage: {
label: "Storage",
icon: "lucide:archive"
},
interface: {
label: "Interface",
icon: "lucide:app-window-mac"
},
other: {
label: "Other",
icon: "lucide:folder"
}
},
ui: {
colors: {
primary: "green",
@@ -37,11 +55,11 @@ export default defineAppConfig({
slots: {
trigger: "cursor-pointer",
item: "md:py-2"
},
}
},
navigationMenu: {
slots: {
link: "cursor-pointer",
link: "cursor-pointer"
},
variants: {
disabled: {

View File

@@ -1,4 +1,4 @@
@import "tailwindcss";
@import "tailwindcss" theme(static);
@import "@nuxt/ui";
@theme {

View File

@@ -13,6 +13,7 @@
variant="link"
:ui="{
root: 'hidden md:flex',
viewportWrapper: 'max-w-2xl absolute-center-h',
list: 'md:gap-x-2'
}"
/>

View File

@@ -3,7 +3,7 @@
<template #title>
<div class="flex gap-x-3">
<Icon name="local:logo" class="size-6" />
<span>NUXTOR</span>
<span class="uppercase">{{ name }}</span>
</div>
</template>
<template #description>
@@ -20,6 +20,7 @@
</template>
<script lang="ts" setup>
const { app: { name } } = useAppConfig();
const { pages } = usePages();
const { showSidebar } = useSidebar();
const tauriVersion = await useTauriAppGetTauriVersion();

View File

@@ -1,13 +1,33 @@
export const usePages = () => {
const router = useRouter();
const { pageCategories } = useAppConfig();
const pages = router.getRoutes().filter((route) => route.name !== "index" && route.name !== "all").map((route) => {
return {
label: route.meta.name,
to: route.path,
icon: route.meta.icon
};
});
const routes = router.getRoutes().filter((route) => route.name !== "index" && route.name !== "all");
const categorizedRoutes = routes.reduce((acc, route) => {
const category = route.meta.category as string || "other";
if (!category) return acc;
if (!acc[category]) {
acc[category] = {
label: pageCategories[category as keyof typeof pageCategories]?.label,
icon: pageCategories[category as keyof typeof pageCategories]?.icon || "i-lucide-folder",
to: route.path,
children: []
};
}
acc[category].children.push({
label: route.meta.name as string || route.name,
description: route.meta.description as string,
icon: route.meta.icon || "i-lucide-file",
to: route.path
});
return acc;
}, {} as Record<string, any>);
const pages = Object.values(categorizedRoutes);
return {
pages

View File

@@ -1,4 +1,5 @@
import * as tauriApp from "@tauri-apps/api/app";
import * as tauriWebviewWindow from "@tauri-apps/api/webviewWindow";
import * as tauriFs from "@tauri-apps/plugin-fs";
import * as tauriNotification from "@tauri-apps/plugin-notification";
import * as tauriOs from "@tauri-apps/plugin-os";
@@ -12,6 +13,7 @@ const capitalize = (name: string) => {
const tauriModules = [
{ module: tauriApp, prefix: "App", importPath: "@tauri-apps/api/app" },
{ module: tauriWebviewWindow, prefix: "WebviewWindow", importPath: "@tauri-apps/api/webviewWindow" },
{ module: tauriShell, prefix: "Shell", importPath: "@tauri-apps/plugin-shell" },
{ module: tauriOs, prefix: "Os", importPath: "@tauri-apps/plugin-os" },
{ module: tauriNotification, prefix: "Notification", importPath: "@tauri-apps/plugin-notification" },

View File

@@ -25,8 +25,10 @@
<script lang="ts" setup>
definePageMeta({
name: "Commands",
icon: "lucide:square-terminal"
name: "Shell commands",
icon: "lucide:terminal",
description: "Execute shell commands",
category: "system"
});
const schema = z.object({

View File

@@ -22,7 +22,9 @@
<script lang="ts" setup>
definePageMeta({
name: "Files",
icon: "lucide:file-text"
icon: "lucide:file-text",
category: "storage",
description: "Create and manage files"
});
const schema = z.object({

View File

@@ -22,7 +22,9 @@
<script lang="ts" setup>
definePageMeta({
name: "Notifications",
icon: "lucide:message-square-more"
icon: "lucide:message-square-more",
category: "interface",
description: "Send native notifications"
});
const schema = z.object({

View File

@@ -10,7 +10,9 @@
<script lang="ts" setup>
definePageMeta({
name: "OS Informations",
icon: "lucide:info"
icon: "lucide:info",
category: "system",
description: "Read operating system informations."
});
const items = ref([

View File

@@ -26,7 +26,9 @@
<script lang="ts" setup>
definePageMeta({
name: "Store",
icon: "lucide:database"
icon: "lucide:database",
category: "storage",
description: "Handle file creation in the file system"
});
const schema = z.object({

51
app/pages/webview.vue Normal file
View File

@@ -0,0 +1,51 @@
<template>
<LayoutTile
title="Webview window"
description="Create new webview in a detached window. This will create a new window flagged 'secondary' that has the same permissions as the main one. If you need more windows, update the permissions under capabilities > main or create a new capabilities file for the new window only."
>
<div class="flex flex-col items-center gap-6">
<UButton variant="subtle" @click="openWindow((new Date).valueOf().toString(), app.repo)">
Create external Webview
</UButton>
<UButton variant="subtle" @click="openWindow('secondary', '/os')">
Create internal Webview
</UButton>
</div>
</LayoutTile>
</template>
<script lang="ts" setup>
definePageMeta({
name: "Webview",
icon: "lucide:app-window",
category: "interface",
description: "Create new webview in a detached window"
});
const { app } = useAppConfig();
const toast = useToast();
const openWindow = async (id: string, page: string) => {
const webview = new useTauriWebviewWindowWebviewWindow(id, {
title: "Nuxtor webview",
url: page,
width: 1280,
height: 720
});
webview.once("tauri://created", () => {
toast.add({
title: "Success",
description: "Webview created",
color: "success"
});
});
webview.once("tauri://error", (error) => {
toast.add({
title: "Error",
description: (error as any).payload,
color: "error"
});
});
};
</script>

22
app/router.options.ts Normal file
View File

@@ -0,0 +1,22 @@
import type { RouterOptions } from "@nuxt/schema";
export default {
scrollBehavior(to, _from, savedPosition) {
return new Promise((resolve, _reject) => {
setTimeout(() => {
if (savedPosition) {
resolve(savedPosition);
} else {
if (to.hash) {
resolve({
el: to.hash,
top: 0
});
} else {
resolve({ top: 0 });
}
}
}, 100);
});
}
} satisfies RouterOptions;

View File

@@ -29,6 +29,7 @@ export default eslintConfig(
"vue/comma-dangle": ["warn", "never"],
"antfu/top-level-function": "off",
"antfu/if-newline": "off",
"new-cap": "off",
"node/prefer-global/process": ["off"]
}
},

View File

@@ -46,11 +46,14 @@ export default defineNuxtConfig({
presets: [
{
from: "zod",
imports: ["z", {
name: "infer",
as: "zInfer",
type: true
}]
imports: [
"z",
{
name: "infer",
as: "zInfer",
type: true
}
]
}
]
},
@@ -72,6 +75,11 @@ export default defineNuxtConfig({
devServer: {
host: "0.0.0.0"
},
router: {
options: {
scrollBehaviorType: "smooth"
}
},
eslint: {
config: {
standalone: false
@@ -83,5 +91,5 @@ export default defineNuxtConfig({
future: {
compatibilityVersion: 4
},
compatibilityDate: "2025-02-01"
compatibilityDate: "2025-03-01"
});

View File

@@ -1,9 +1,9 @@
{
"name": "nuxtor",
"type": "module",
"version": "1.2.0",
"version": "1.3.0",
"private": true,
"packageManager": "pnpm@9.15.4",
"packageManager": "pnpm@10.6.2",
"description": "Starter template for Nuxt 3 and Tauri 2",
"author": "Nicola Spadari",
"license": "MIT",
@@ -23,27 +23,30 @@
"tauri:build:debug": "tauri build --debug"
},
"dependencies": {
"@nuxt/ui": "3.0.0-alpha.12",
"@tauri-apps/api": ">=2.2.0",
"@nuxt/ui": "^3.0.0-beta.3",
"@tauri-apps/api": "^2.3.0",
"@tauri-apps/plugin-fs": "^2.2.0",
"@tauri-apps/plugin-notification": "^2.2.1",
"@tauri-apps/plugin-os": "^2.2.0",
"@tauri-apps/plugin-shell": "^2.2.0",
"@tauri-apps/plugin-store": "^2.2.0",
"nuxt": "^3.15.4",
"nuxt": "^3.16.0",
"vue": "^3.5.13",
"vue-router": "^4.5.0",
"zod": "^3.24.1"
"zod": "^3.24.2"
},
"devDependencies": {
"@antfu/eslint-config": "^4.1.1",
"@nuxt/eslint": "^1.0.1",
"@tauri-apps/cli": ">=2.2.7",
"@vueuse/core": "^12.5.0",
"@vueuse/nuxt": "^12.5.0",
"bumpp": "^10.0.2",
"eslint": "9.17.0",
"nuxt-svgo": "^4.0.14",
"typescript": "^5.7.3"
"@antfu/eslint-config": "^4.8.1",
"@nuxt/eslint": "^1.2.0",
"@tauri-apps/cli": "^2.3.1",
"@vueuse/core": "^13.0.0",
"@vueuse/nuxt": "^13.0.0",
"bumpp": "^10.0.3",
"eslint": "^9.22.0",
"nuxt-svgo": "^4.0.15",
"typescript": "^5.8.2"
},
"resolutions": {
"typescript": "npm:tslite@latest"
}
}

3897
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

63
preview.md Normal file
View File

@@ -0,0 +1,63 @@
# Preview
Since Nuxtor is a desktop application, there is no way of showing the look and feel of the released project.
What follows are each page and its functionalities:
## Commands page
Access the system shell
<div align="center">
<img src="./public/page-commands.png">
</div>
---
## File system page
Access the file system
<div align="center">
<img src="./public/page-file-system.png">
</div>
---
## Notifications page
Send custom notifications at os-level
<div align="center">
<img src="./public/page-notifications.png">
</div>
---
## OS info page
Show system informations
<div align="center">
<img src="./public/page-os-info.png">
</div>
---
## Storage page
Read & write persistent key-value data
<div align="center">
<img src="./public/page-storage.png">
</div>
---
## Webview page
Create a secondary detached window
<div align="center">
<img src="./public/page-webview.png">
</div>

BIN
public/page-commands.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

BIN
public/page-file-system.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
public/page-os-info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

BIN
public/page-storage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
public/page-webview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 KiB

After

Width:  |  Height:  |  Size: 423 KiB

View File

@@ -1,6 +1,6 @@
[package]
name = "nuxtor"
version = "1.2.0"
version = "1.3.0"
description = "Starter template for Nuxt 3 and Tauri 2"
authors = [ "NicolaSpadari" ]
license = "MIT"
@@ -29,7 +29,10 @@ serde_json = "1"
[dependencies.tauri]
version = "2.2.5"
features = [ "tray-icon" ]
features = [
"tray-icon",
"unstable"
]
[dependencies.serde]
version = "1"

View File

@@ -1,9 +1,10 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main",
"description": "Capabilities for the main window",
"description": "Capabilities for the app window",
"windows": [
"main"
"main",
"secondary"
],
"permissions": [
"core:path:default",
@@ -38,6 +39,8 @@
"os:allow-locale",
"fs:allow-document-read",
"fs:allow-document-write",
"store:default"
"store:default",
"core:webview:allow-create-webview",
"core:webview:allow-create-webview-window"
]
}

View File

@@ -1 +1 @@
{"main":{"identifier":"main","description":"Capabilities for the main window","local":true,"windows":["main"],"permissions":["core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","shell:allow-open",{"identifier":"shell:allow-execute","allow":[{"args":["-c",{"validator":"\\S+"}],"cmd":"sh","name":"exec-sh","sidecar":false}]},"notification:default","os:allow-platform","os:allow-arch","os:allow-family","os:allow-version","os:allow-locale","fs:allow-document-read","fs:allow-document-write","store:default"]}}
{"main":{"identifier":"main","description":"Capabilities for the app window","local":true,"windows":["main","secondary"],"permissions":["core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","shell:allow-open",{"identifier":"shell:allow-execute","allow":[{"args":["-c",{"validator":"\\S+"}],"cmd":"sh","name":"exec-sh","sidecar":false}]},"notification:default","os:allow-platform","os:allow-arch","os:allow-family","os:allow-version","os:allow-locale","fs:allow-document-read","fs:allow-document-write","store:default","core:webview:allow-create-webview","core:webview:allow-create-webview-window"]}}

View File

@@ -32,7 +32,7 @@
"devUrl": "http://localhost:3000"
},
"productName": "Nuxtor",
"version": "1.2.0",
"version": "1.3.0",
"identifier": "com.nicolaspadari.nuxtor",
"plugins": {},
"app": {