style: formatting

This commit is contained in:
PandaDEV 2024-11-23 14:57:42 +10:00
parent 7e6b2f8b63
commit f2f554074b
No known key found for this signature in database
GPG key ID: 13EFF9BAF70EE75C
22 changed files with 1493 additions and 1171 deletions

214
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,214 @@
name: "Release"
on:
push:
tags:
- "v*"
workflow_dispatch:
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get_version.outputs.VERSION }}
steps:
- uses: actions/checkout@v4
- name: Get version
id: get_version
run: echo "VERSION=$(node -p "require('./src-tauri/tauri.conf.json').version")" >> $GITHUB_OUTPUT
build-macos:
needs: prepare
strategy:
matrix:
include:
- args: "--target aarch64-apple-darwin"
arch: "silicon"
- args: "--target x86_64-apple-darwin"
arch: "intel"
runs-on: macos-latest
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
steps:
- uses: actions/checkout@v4
- name: Redact Sensitive Information
run: |
function redact_output {
sed -e "s/${{ secrets.REDACT_PATTERN }}/REDACTED/g"
}
exec > >(redact_output) 2>&1
- uses: actions/setup-node@v4
with:
node-version: 20
- uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin,x86_64-apple-darwin
- uses: swatinem/rust-cache@v2
with:
workspaces: "src-tauri -> target"
cache-directories: "~/.cargo/registry/index/,~/.cargo/registry/cache/,~/.cargo/git/db/"
shared-key: "macos-rust-cache"
save-if: "true"
- uses: actions/cache@v4
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
- run: npm install -g pnpm && pnpm install
- name: Import Apple Developer Certificate
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
args: ${{ matrix.args }}
tagName: v${{ needs.prepare.outputs.version }}
releaseName: v${{ needs.prepare.outputs.version }}
releaseBody: "See the assets to download this version and install."
releaseDraft: true
prerelease: false
- name: Rename macOS Artifacts
run: |
mv src-tauri/target/${{ matrix.args == '--target aarch64-apple-darwin' && 'aarch64-apple-darwin' || 'x86_64-apple-darwin' }}/release/bundle/dmg/*.dmg src-tauri/target/${{ matrix.args == '--target aarch64-apple-darwin' && 'aarch64-apple-darwin' || 'x86_64-apple-darwin' }}/release/bundle/dmg/Qopy-${{ needs.prepare.outputs.version }}_${{ matrix.arch }}.dmg
mv src-tauri/target/${{ matrix.args == '--target aarch64-apple-darwin' && 'aarch64-apple-darwin' || 'x86_64-apple-darwin' }}/release/bundle/macos/*.app.tar.gz src-tauri/target/${{ matrix.args == '--target aarch64-apple-darwin' && 'aarch64-apple-darwin' || 'x86_64-apple-darwin' }}/release/bundle/macos/Qopy-${{ needs.prepare.outputs.version }}_${{ matrix.arch }}.app.tar.gz
mv src-tauri/target/${{ matrix.args == '--target aarch64-apple-darwin' && 'aarch64-apple-darwin' || 'x86_64-apple-darwin' }}/release/bundle/macos/*.app.tar.gz.sig src-tauri/target/${{ matrix.args == '--target aarch64-apple-darwin' && 'aarch64-apple-darwin' || 'x86_64-apple-darwin' }}/release/bundle/macos/Qopy-${{ needs.prepare.outputs.version }}_${{ matrix.arch }}.app.tar.gz.sig
build-windows:
needs: prepare
strategy:
matrix:
include:
- args: "--target x86_64-pc-windows-msvc"
arch: "x64"
- args: "--target aarch64-pc-windows-msvc"
arch: "arm64"
runs-on: windows-latest
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-pc-windows-msvc,aarch64-pc-windows-msvc
- uses: swatinem/rust-cache@v2
with:
workspaces: "src-tauri -> target"
cache-directories: "~/.cargo/registry/index/,~/.cargo/registry/cache/,~/.cargo/git/db/"
shared-key: "windows-rust-cache"
save-if: "true"
- uses: actions/cache@v4
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
- run: npm install -g pnpm && pnpm install
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
args: ${{ matrix.args }}
tagName: v${{ needs.prepare.outputs.version }}
releaseName: v${{ needs.prepare.outputs.version }}
releaseBody: "See the assets to download this version and install."
releaseDraft: true
prerelease: false
- name: Rename Windows Artifacts
run: |
mv src-tauri/target/release/bundle/msi/*.msi src-tauri/target/release/bundle/msi/Qopy-${{ needs.prepare.outputs.version }}_${{ matrix.arch }}.msi
mv src-tauri/target/release/bundle/msi/*.msi.sig src-tauri/target/release/bundle/msi/Qopy-${{ needs.prepare.outputs.version }}_${{ matrix.arch }}.msi.sig
build-linux:
needs: prepare
runs-on: ubuntu-latest
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
- uses: dtolnay/rust-toolchain@stable
- uses: swatinem/rust-cache@v2
with:
workspaces: "src-tauri -> target"
cache-directories: "~/.cargo/registry/index/,~/.cargo/registry/cache/,~/.cargo/git/db/"
shared-key: "linux-rust-cache"
save-if: "true"
- uses: actions/cache@v4
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y libwebkit2gtk-4.1-dev build-essential curl wget file libssl-dev libayatana-appindicator3-dev librsvg2-dev libasound2-dev rpm
echo "PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig" >> $GITHUB_ENV
- run: npm install -g pnpm && pnpm install
- name: Generate Changelog
id: changelog
run: |
CHANGELOG=$(git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"- %s")
echo "CHANGELOG<<EOF" >> $GITHUB_ENV
echo "$CHANGELOG" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
args: --target x86_64-unknown-linux-gnu
tagName: v${{ needs.prepare.outputs.version }}
releaseName: v${{ needs.prepare.outputs.version }}
releaseBody: |
## Changelog
${{ env.CHANGELOG }}
See the assets to download this version and install.
releaseDraft: true
prerelease: false
- name: Rename Linux Artifacts
run: |
mv src-tauri/target/release/bundle/deb/*.deb src-tauri/target/release/bundle/deb/Qopy-${{ needs.prepare.outputs.version }}_amd64.deb
mv src-tauri/target/release/bundle/appimage/*.AppImage src-tauri/target/release/bundle/appimage/Qopy-${{ needs.prepare.outputs.version }}_amd64.AppImage
mv src-tauri/target/release/bundle/appimage/*.AppImage.sig src-tauri/target/release/bundle/appimage/Qopy-${{ needs.prepare.outputs.version }}_amd64.AppImage.sig
mv src-tauri/target/release/bundle/rpm/*.rpm src-tauri/target/release/bundle/rpm/Qopy-${{ needs.prepare.outputs.version }}_amd64.rpm
- name: Create Draft Release
uses: softprops/action-gh-release@v1
with:
draft: true
files: |
src-tauri/target/release/bundle/deb/*.deb
src-tauri/target/release/bundle/appimage/*.AppImage
src-tauri/target/release/bundle/appimage/*.AppImage.sig
src-tauri/target/release/bundle/rpm/*.rpm
body: |
## Changelog
${{ env.CHANGELOG }}
See the assets to download this version and install.
tag_name: v${{ needs.prepare.outputs.version }}
name: v${{ needs.prepare.outputs.version }}

39
.prettierignore Normal file
View file

@ -0,0 +1,39 @@
# Rust
/target/
/src-tauri/target/
Cargo.lock
*.rs
# Node
node_modules/
.nuxt/
.output/
dist/
# Build
/build/
/out/
# Tauri
.tauri/
# System
.DS_Store
*.pem
# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Local env files
.env
.env.*
# IDE
.idea/
.vscode/
*.suo
*.ntvs*
*.njsproj
*.sln

10
.prettierrc Normal file
View file

@ -0,0 +1,10 @@
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"useTabs": true,
"printWidth": 100,
"trailingComma": "es5",
"vueIndentScriptAndStyle": true,
"plugins": ["prettier-plugin-vue"]
}

View file

@ -5,9 +5,9 @@ The hotkey for Qopy is Windows+V which is also the hotkey for the default clipbo
All the data of Qopy is stored inside of a SQLite database. The location for the file differs for windows and linux.
| Operating System | Path |
|------------------|-------------------------------------------------------|
| ---------------- | ----------------------------------------------------- |
| Windows | `C:\Users\USERNAME\AppData\Roaming\net.pandadev.qopy` |
| Linux | `` |
| Linux | `` |
## Disable Windows+V for default clipboard manager

View file

@ -60,6 +60,7 @@ The fixed and simple clipboard manager for both Windows and Linux.
Qopy is a fixed clipboard manager designed as a simple alternative to the standard clipboard on Windows. It aims to provide a faster, more reliable experience while providing an extensive set of features compared to its Windows counterpart.
## 🚧 Roadmap
- [ ] [Setup guide](https://github.com/0PandaDEV/Qopy/blob/main/GET_STARTED.md)
- [ ] Settings https://github.com/0PandaDEV/Qopy/issues/2
- [ ] Metadata for copied items https://github.com/0PandaDEV/Qopy/issues/5
@ -72,6 +73,7 @@ Qopy is a fixed clipboard manager designed as a simple alternative to the standa
<sup>If you have ideas for features to include, please write a feature request [here](https://github.com/0pandadev/Qopy/issues).</sup>
## 📦 Preview
<img width="800px" src="https://github.com/user-attachments/assets/18e1f9e3-414c-46e2-9c51-61c6e63a06d2"/>
<img width="800px" src="https://github.com/user-attachments/assets/46ec4672-f156-4426-a2cb-3a40d00dbcd6"/>

46
app.vue
View file

@ -1,31 +1,31 @@
<template>
<div>
<NuxtPage />
</div>
<div>
<NuxtPage />
</div>
</template>
<script setup lang="ts">
import { listen } from '@tauri-apps/api/event'
import { app, window } from '@tauri-apps/api';
import { onMounted } from 'vue'
import { app, window } from "@tauri-apps/api";
import { listen } from "@tauri-apps/api/event";
import { onMounted } from "vue";
onMounted(async () => {
await listen('change_keybind', async () => {
console.log("change_keybind");
await navigateTo('/keybind')
await app.show();
await window.getCurrentWindow().show();
})
onMounted(async () => {
await listen("change_keybind", async () => {
console.log("change_keybind");
await navigateTo("/keybind");
await app.show();
await window.getCurrentWindow().show();
});
await listen('main_route', async () => {
console.log("main_route");
await navigateTo('/')
})
})
await listen("main_route", async () => {
console.log("main_route");
await navigateTo("/");
});
});
</script>
<style lang="scss">
@font-face {
@font-face {
font-family: SFRoundedRegular;
font-display: swap;
src: url("~/assets/fonts/SFRoundedRegular.otf") format("opentype");
@ -53,16 +53,16 @@ onMounted(async () => {
margin: 0;
padding: 0;
box-sizing: border-box;
color: #E5DFD5;
color: #e5dfd5;
text-decoration: none;
font-family: SFRoundedRegular;
scroll-behavior: smooth;
scrollbar-width: thin;
user-select: none;
--os-handle-bg: #ADA9A1;
--os-handle-bg-hover: #78756F;
--os-handle-bg-active: #78756F;
--os-handle-bg: #ada9a1;
--os-handle-bg-hover: #78756f;
--os-handle-bg-active: #78756f;
}
html,

View file

@ -7,295 +7,295 @@ $text2: #ada9a1;
$mutedtext: #78756f;
.bg {
width: 750px;
height: 474px;
background-color: $primary;
border: 1px solid $divider;
border-radius: 12px;
z-index: -1;
position: fixed;
outline: none;
width: 750px;
height: 474px;
background-color: $primary;
border: 1px solid $divider;
border-radius: 12px;
z-index: -1;
position: fixed;
outline: none;
}
.search {
width: 100%;
position: fixed;
top: 0;
left: 0;
height: 54px;
background-color: transparent;
outline: none;
border: none;
font-size: 18px;
color: $mutedtext;
padding-inline: 16px;
border-bottom: 1px solid $divider;
font-family: SFRoundedMedium;
width: 100%;
position: fixed;
top: 0;
left: 0;
height: 54px;
background-color: transparent;
outline: none;
border: none;
font-size: 18px;
color: $mutedtext;
padding-inline: 16px;
border-bottom: 1px solid $divider;
font-family: SFRoundedMedium;
}
.results {
position: absolute;
width: 284px;
top: 53px;
left: 0;
height: calc(100vh - 95px);
border-right: 1px solid $divider;
display: flex;
flex-direction: column;
padding-inline: 8px;
padding-bottom: 8px;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
width: 284px;
top: 53px;
left: 0;
height: calc(100vh - 95px);
border-right: 1px solid $divider;
display: flex;
flex-direction: column;
padding-inline: 8px;
padding-bottom: 8px;
overflow-y: auto;
overflow-x: hidden;
.result {
height: 40px;
font-size: 14px;
align-items: center;
display: flex;
padding: 10px;
padding-inline: 10px;
letter-spacing: 0.5px;
gap: 10px;
overflow: hidden;
text-overflow: clip;
white-space: nowrap;
}
.result {
height: 40px;
font-size: 14px;
align-items: center;
display: flex;
padding: 10px;
padding-inline: 10px;
letter-spacing: 0.5px;
gap: 10px;
overflow: hidden;
text-overflow: clip;
white-space: nowrap;
}
.result {
cursor: pointer;
.result {
cursor: pointer;
&.selected {
background-color: $divider;
}
}
&.selected {
background-color: $divider;
}
}
.time-separator {
font-size: 12px;
color: $text2;
font-family: SFRoundedSemiBold;
padding-left: 8px;
padding-bottom: 8px;
padding-top: 14px;
}
.time-separator {
font-size: 12px;
color: $text2;
font-family: SFRoundedSemiBold;
padding-left: 8px;
padding-bottom: 8px;
padding-top: 14px;
}
.favicon {
width: 18px;
height: 18px;
}
.favicon {
width: 18px;
height: 18px;
}
.image {
width: 18px;
height: 18px;
}
.image {
width: 18px;
height: 18px;
}
.icon {
width: 20px;
height: 18px;
}
.icon {
width: 20px;
height: 18px;
}
}
.content {
position: absolute;
top: 53px;
left: 284px;
padding: 8px;
height: calc(100vh - 96px);
font-family: CommitMono Nerd Font !important;
font-size: 14px;
letter-spacing: 1;
border-radius: 10px;
width: calc(100vw - 286px);
white-space: pre-wrap;
word-wrap: break-word;
position: absolute;
top: 53px;
left: 284px;
padding: 8px;
height: calc(100vh - 96px);
font-family: CommitMono Nerd Font !important;
font-size: 14px;
letter-spacing: 1;
border-radius: 10px;
width: calc(100vw - 286px);
white-space: pre-wrap;
word-wrap: break-word;
span {
font-family: CommitMono Nerd Font !important;
}
span {
font-family: CommitMono Nerd Font !important;
}
.full-image {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
object-position: center;
}
.full-image {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
object-position: center;
}
.image {
max-width: 100%;
max-height: 100%;
object-fit: contain;
object-position: top left;
}
.image {
max-width: 100%;
max-height: 100%;
object-fit: contain;
object-position: top left;
}
}
.bottom-bar {
height: 40px;
width: calc(100vw - 2px);
backdrop-filter: blur(18px);
background-color: hsla(40, 3%, 16%, 0.8);
position: fixed;
bottom: 1px;
left: 1px;
z-index: 100;
border-radius: 0 0 12px 12px;
display: flex;
flex-direction: row;
justify-content: space-between;
padding-inline: 12px;
padding-right: 6px;
padding-top: 1px;
align-items: center;
font-size: 14px;
border-top: 1px solid $divider;
height: 40px;
width: calc(100vw - 2px);
backdrop-filter: blur(18px);
background-color: hsla(40, 3%, 16%, 0.8);
position: fixed;
bottom: 1px;
left: 1px;
z-index: 100;
border-radius: 0 0 12px 12px;
display: flex;
flex-direction: row;
justify-content: space-between;
padding-inline: 12px;
padding-right: 6px;
padding-top: 1px;
align-items: center;
font-size: 14px;
border-top: 1px solid $divider;
p {
color: $text2;
}
p {
color: $text2;
}
.left {
display: flex;
align-items: center;
gap: 8px;
.left {
display: flex;
align-items: center;
gap: 8px;
.logo {
width: 18px;
height: 18px;
}
}
.logo {
width: 18px;
height: 18px;
}
}
.right {
display: flex;
align-items: center;
.right {
display: flex;
align-items: center;
.paste p {
color: $text;
}
.paste p {
color: $text;
}
.actions div {
display: flex;
align-items: center;
gap: 2px;
}
.actions div {
display: flex;
align-items: center;
gap: 2px;
}
.divider {
width: 2px;
height: 12px;
background-color: $divider;
margin-left: 8px;
margin-right: 4px;
transition: all 0.2s;
}
.divider {
width: 2px;
height: 12px;
background-color: $divider;
margin-left: 8px;
margin-right: 4px;
transition: all 0.2s;
}
.paste,
.actions {
padding: 4px;
padding-left: 8px;
display: flex;
align-items: center;
gap: 8px;
border-radius: 7px;
background-color: transparent;
transition: all 0.2s;
cursor: pointer;
}
.paste,
.actions {
padding: 4px;
padding-left: 8px;
display: flex;
align-items: center;
gap: 8px;
border-radius: 7px;
background-color: transparent;
transition: all 0.2s;
cursor: pointer;
}
.paste:hover,
.actions:hover {
background-color: $divider;
}
.paste:hover,
.actions:hover {
background-color: $divider;
}
&:hover .paste:hover ~ .divider,
&:hover .actions:hover ~ .divider {
opacity: 0;
}
}
&:hover .paste:hover ~ .divider,
&:hover .actions:hover ~ .divider {
opacity: 0;
}
}
}
.clothoid-corner {
clip-path: polygon(
13.890123px 0px,
calc(100% - 13.890123px) 0px,
calc(100% - 12.723414px) 0.004211px,
calc(100% - 11.556933px) 0.025635px,
calc(100% - 10.391895px) 0.085062px,
calc(100% - 9.231074px) 0.199291px,
calc(100% - 8.079275px) 0.382298px,
calc(100% - 6.947448px) 0.662609px,
calc(100% - 5.844179px) 1.039291px,
calc(100% - 4.793324px) 1.542842px,
calc(100% - 3.811369px) 2.169728px,
calc(100% - 2.926417px) 2.926417px,
calc(100% - 2.169728px) 3.811369px,
calc(100% - 1.542842px) 4.793324px,
calc(100% - 1.039291px) 5.844179px,
calc(100% - 0.662609px) 6.947448px,
calc(100% - 0.382298px) 8.079275px,
calc(100% - 0.199291px) 9.231074px,
calc(100% - 0.085062px) 10.391895px,
calc(100% - 0.025635px) 11.556933px,
calc(100% - 0.004211px) 12.723414px,
100% 13.890123px,
100% calc(100% - 13.890123px),
calc(100% - 0.004211px) calc(100% - 12.723414px),
calc(100% - 0.025635px) calc(100% - 11.556933px),
calc(100% - 0.085062px) calc(100% - 10.391895px),
calc(100% - 0.199291px) calc(100% - 9.231074px),
calc(100% - 0.382298px) calc(100% - 8.079275px),
calc(100% - 0.662609px) calc(100% - 6.947448px),
calc(100% - 1.039291px) calc(100% - 5.844179px),
calc(100% - 1.542842px) calc(100% - 4.793324px),
calc(100% - 2.169728px) calc(100% - 3.811369px),
calc(100% - 2.926417px) calc(100% - 2.926417px),
calc(100% - 3.811369px) calc(100% - 2.169728px),
calc(100% - 4.793324px) calc(100% - 1.542842px),
calc(100% - 5.844179px) calc(100% - 1.039291px),
calc(100% - 6.947448px) calc(100% - 0.662609px),
calc(100% - 8.079275px) calc(100% - 0.382298px),
calc(100% - 9.231074px) calc(100% - 0.199291px),
calc(100% - 10.391895px) calc(100% - 0.085062px),
calc(100% - 11.556933px) calc(100% - 0.025635px),
calc(100% - 12.723414px) calc(100% - 0.004211px),
calc(100% - 13.890123px) 100%,
13.890123px 100%,
12.723414px calc(100% - 0.004211px),
11.556933px calc(100% - 0.025635px),
10.391895px calc(100% - 0.085062px),
9.231074px calc(100% - 0.199291px),
8.079275px calc(100% - 0.382298px),
6.947448px calc(100% - 0.662609px),
5.844179px calc(100% - 1.039291px),
4.793324px calc(100% - 1.542842px),
3.811369px calc(100% - 2.169728px),
2.926417px calc(100% - 2.926417px),
2.169728px calc(100% - 3.811369px),
1.542842px calc(100% - 4.793324px),
1.039291px calc(100% - 5.844179px),
0.662609px calc(100% - 6.947448px),
0.382298px calc(100% - 8.079275px),
0.199291px calc(100% - 9.231074px),
0.085062px calc(100% - 10.391895px),
0.025635px calc(100% - 11.556933px),
0.004211px calc(100% - 12.723414px),
0px calc(100% - 13.890123px),
0px 13.890123px,
0.004211px 12.723414px,
0.025635px 11.556933px,
0.085062px 10.391895px,
0.199291px 9.231074px,
0.382298px 8.079275px,
0.662609px 6.947448px,
1.039291px 5.844179px,
1.542842px 4.793324px,
2.169728px 3.811369px,
2.926417px 2.926417px,
3.811369px 2.169728px,
4.793324px 1.542842px,
5.844179px 1.039291px,
6.947448px 0.662609px,
8.079275px 0.382298px,
9.231074px 0.199291px,
10.391895px 0.085062px,
11.556933px 0.025635px,
12.723414px 0.004211px,
13.890123px 0px
);
clip-path: polygon(
13.890123px 0px,
calc(100% - 13.890123px) 0px,
calc(100% - 12.723414px) 0.004211px,
calc(100% - 11.556933px) 0.025635px,
calc(100% - 10.391895px) 0.085062px,
calc(100% - 9.231074px) 0.199291px,
calc(100% - 8.079275px) 0.382298px,
calc(100% - 6.947448px) 0.662609px,
calc(100% - 5.844179px) 1.039291px,
calc(100% - 4.793324px) 1.542842px,
calc(100% - 3.811369px) 2.169728px,
calc(100% - 2.926417px) 2.926417px,
calc(100% - 2.169728px) 3.811369px,
calc(100% - 1.542842px) 4.793324px,
calc(100% - 1.039291px) 5.844179px,
calc(100% - 0.662609px) 6.947448px,
calc(100% - 0.382298px) 8.079275px,
calc(100% - 0.199291px) 9.231074px,
calc(100% - 0.085062px) 10.391895px,
calc(100% - 0.025635px) 11.556933px,
calc(100% - 0.004211px) 12.723414px,
100% 13.890123px,
100% calc(100% - 13.890123px),
calc(100% - 0.004211px) calc(100% - 12.723414px),
calc(100% - 0.025635px) calc(100% - 11.556933px),
calc(100% - 0.085062px) calc(100% - 10.391895px),
calc(100% - 0.199291px) calc(100% - 9.231074px),
calc(100% - 0.382298px) calc(100% - 8.079275px),
calc(100% - 0.662609px) calc(100% - 6.947448px),
calc(100% - 1.039291px) calc(100% - 5.844179px),
calc(100% - 1.542842px) calc(100% - 4.793324px),
calc(100% - 2.169728px) calc(100% - 3.811369px),
calc(100% - 2.926417px) calc(100% - 2.926417px),
calc(100% - 3.811369px) calc(100% - 2.169728px),
calc(100% - 4.793324px) calc(100% - 1.542842px),
calc(100% - 5.844179px) calc(100% - 1.039291px),
calc(100% - 6.947448px) calc(100% - 0.662609px),
calc(100% - 8.079275px) calc(100% - 0.382298px),
calc(100% - 9.231074px) calc(100% - 0.199291px),
calc(100% - 10.391895px) calc(100% - 0.085062px),
calc(100% - 11.556933px) calc(100% - 0.025635px),
calc(100% - 12.723414px) calc(100% - 0.004211px),
calc(100% - 13.890123px) 100%,
13.890123px 100%,
12.723414px calc(100% - 0.004211px),
11.556933px calc(100% - 0.025635px),
10.391895px calc(100% - 0.085062px),
9.231074px calc(100% - 0.199291px),
8.079275px calc(100% - 0.382298px),
6.947448px calc(100% - 0.662609px),
5.844179px calc(100% - 1.039291px),
4.793324px calc(100% - 1.542842px),
3.811369px calc(100% - 2.169728px),
2.926417px calc(100% - 2.926417px),
2.169728px calc(100% - 3.811369px),
1.542842px calc(100% - 4.793324px),
1.039291px calc(100% - 5.844179px),
0.662609px calc(100% - 6.947448px),
0.382298px calc(100% - 8.079275px),
0.199291px calc(100% - 9.231074px),
0.085062px calc(100% - 10.391895px),
0.025635px calc(100% - 11.556933px),
0.004211px calc(100% - 12.723414px),
0px calc(100% - 13.890123px),
0px 13.890123px,
0.004211px 12.723414px,
0.025635px 11.556933px,
0.085062px 10.391895px,
0.199291px 9.231074px,
0.382298px 8.079275px,
0.662609px 6.947448px,
1.039291px 5.844179px,
1.542842px 4.793324px,
2.169728px 3.811369px,
2.926417px 2.926417px,
3.811369px 2.169728px,
4.793324px 1.542842px,
5.844179px 1.039291px,
6.947448px 0.662609px,
8.079275px 0.382298px,
9.231074px 0.199291px,
10.391895px 0.085062px,
11.556933px 0.025635px,
12.723414px 0.004211px,
13.890123px 0px
);
}

View file

@ -1,149 +1,149 @@
$primary: #2E2D2B;
$accent: #FEB453;
$primary: #2e2d2b;
$accent: #feb453;
$divider: #ffffff0d;
$text: #E5DFD5;
$text2: #ADA9A1;
$mutedtext: #78756F;
$text: #e5dfd5;
$text2: #ada9a1;
$mutedtext: #78756f;
.bg {
width: 750px;
height: 474px;
background-color: $primary;
border: 1px solid $divider;
border-radius: 12px;
z-index: -1;
position: fixed;
outline: none;
width: 750px;
height: 474px;
background-color: $primary;
border: 1px solid $divider;
border-radius: 12px;
z-index: -1;
position: fixed;
outline: none;
}
.back {
position: absolute;
top: 16px;
left: 16px;
display: flex;
gap: 8px;
align-items: center;
position: absolute;
top: 16px;
left: 16px;
display: flex;
gap: 8px;
align-items: center;
img{
background-color: $divider;
border-radius: 6px;
padding: 8px 6px;
}
img {
background-color: $divider;
border-radius: 6px;
padding: 8px 6px;
}
p {
color: $text2;
}
p {
color: $text2;
}
}
.keybind-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
gap: 6px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
gap: 6px;
.title {
font-size: 20px;
font-weight: 800;
}
.title {
font-size: 20px;
font-weight: 800;
}
.keybind-input {
padding: 6px;
border: 1px solid $divider;
color: $text2;
display: flex;
border-radius: 13px;
outline: none;
gap: 6px;
.keybind-input {
padding: 6px;
border: 1px solid $divider;
color: $text2;
display: flex;
border-radius: 13px;
outline: none;
gap: 6px;
.key {
color: $text2;
font-family: SFRoundedMedium;
background-color: $divider;
padding: 6px 8px;
border-radius: 8px;
}
}
.key {
color: $text2;
font-family: SFRoundedMedium;
background-color: $divider;
padding: 6px 8px;
border-radius: 8px;
}
}
.keybind-input:focus {
border: 1px solid rgba(255, 255, 255, 0.2);
}
.keybind-input:focus {
border: 1px solid rgba(255, 255, 255, 0.2);
}
}
.bottom-bar {
height: 40px;
width: calc(100vw - 2px);
backdrop-filter: blur(18px);
background-color: hsla(40, 3%, 16%, 0.8);
position: fixed;
bottom: 1px;
left: 1px;
z-index: 100;
border-radius: 0 0 12px 12px;
display: flex;
flex-direction: row;
justify-content: space-between;
padding-inline: 12px;
padding-right: 6px;
padding-top: 1px;
align-items: center;
font-size: 14px;
border-top: 1px solid $divider;
height: 40px;
width: calc(100vw - 2px);
backdrop-filter: blur(18px);
background-color: hsla(40, 3%, 16%, 0.8);
position: fixed;
bottom: 1px;
left: 1px;
z-index: 100;
border-radius: 0 0 12px 12px;
display: flex;
flex-direction: row;
justify-content: space-between;
padding-inline: 12px;
padding-right: 6px;
padding-top: 1px;
align-items: center;
font-size: 14px;
border-top: 1px solid $divider;
p {
color: $text2;
}
p {
color: $text2;
}
.left {
display: flex;
align-items: center;
gap: 8px;
.left {
display: flex;
align-items: center;
gap: 8px;
.logo {
width: 18px;
height: 18px;
}
}
.logo {
width: 18px;
height: 18px;
}
}
.right {
display: flex;
align-items: center;
.right {
display: flex;
align-items: center;
.actions div {
display: flex;
align-items: center;
gap: 2px;
}
.actions div {
display: flex;
align-items: center;
gap: 2px;
}
.divider {
width: 2px;
height: 12px;
background-color: $divider;
margin-left: 8px;
margin-right: 4px;
transition: all .2s;
}
.divider {
width: 2px;
height: 12px;
background-color: $divider;
margin-left: 8px;
margin-right: 4px;
transition: all 0.2s;
}
.actions {
padding: 4px;
padding-left: 8px;
display: flex;
align-items: center;
gap: 8px;
border-radius: 7px;
background-color: transparent;
transition: all .2s;
cursor: pointer;
}
.actions {
padding: 4px;
padding-left: 8px;
display: flex;
align-items: center;
gap: 8px;
border-radius: 7px;
background-color: transparent;
transition: all 0.2s;
cursor: pointer;
}
.actions:hover {
background-color: $divider;
}
.actions:hover {
background-color: $divider;
}
&:hover .actions:hover~.divider {
opacity: 0;
}
}
&:hover .actions:hover ~ .divider {
opacity: 0;
}
}
}

View file

@ -1,9 +1,9 @@
<template>
<div class="noise"></div>
<div class="noise"></div>
</template>
<style scoped lang="scss">
.noise {
.noise {
position: absolute;
overflow: hidden;
top: 0;
@ -13,7 +13,7 @@
pointer-events: none;
user-select: none;
z-index: 0;
background-image: url('/noise.png');
background-image: url("/noise.png");
background-repeat: repeat;
image-rendering: pixelated;
overflow: hidden;

View file

@ -1,15 +1,15 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: false },
compatibilityDate: "2024-07-04",
ssr: false,
vite: {
css: {
preprocessorOptions: {
scss: {
api: "modern-compiler",
},
},
},
},
devtools: { enabled: false },
compatibilityDate: "2024-07-04",
ssr: false,
vite: {
css: {
preprocessorOptions: {
scss: {
api: "modern-compiler",
},
},
},
},
});

View file

@ -1,26 +1,31 @@
{
"name": "nuxt-app",
"private": true,
"type": "module",
"scripts": {
"build": "tauri build",
"dev": "tauri dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"@tauri-apps/api": "2.0.3",
"@tauri-apps/cli": "2.1.0",
"@tauri-apps/plugin-autostart": "2.0.0",
"@tauri-apps/plugin-fs": "2.0.2",
"@tauri-apps/plugin-os": "2.0.0",
"@tauri-apps/plugin-sql": "2.0.1",
"nuxt": "3.14.159",
"nuxt-build-cache": "0.1.1",
"overlayscrollbars": "2.10.0",
"overlayscrollbars-vue": "0.5.9",
"sass": "1.81.0",
"vue": "3.5.13"
}
"name": "nuxt-app",
"dependencies": {
"@tauri-apps/api": "2.1.1",
"@tauri-apps/cli": "2.1.0",
"@tauri-apps/plugin-autostart": "2.0.0",
"@tauri-apps/plugin-fs": "2.0.2",
"@tauri-apps/plugin-os": "2.0.0",
"@tauri-apps/plugin-sql": "2.0.1",
"nuxt": "3.14.1592",
"nuxt-build-cache": "0.1.1",
"overlayscrollbars": "2.10.0",
"overlayscrollbars-vue": "0.5.9",
"prettier": "^3.3.3",
"sass": "1.81.0",
"vue": "3.5.13"
},
"private": true,
"scripts": {
"build": "tauri build",
"dev": "tauri dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare",
"format": "prettier --write \"**/*.{js,ts,vue,scss,css,json,md}\""
},
"type": "module",
"devDependencies": {
"prettier-plugin-vue": "^1.1.6"
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,176 +1,185 @@
<template>
<div class="bg">
<div class="back">
<img @click="router.push('/')" src="../public/back_arrow.svg" />
<p>Back</p>
</div>
<div class="bottom-bar">
<div class="left">
<img alt="" class="logo" src="../public/logo.png" width="18px" />
<p>Qopy</p>
</div>
<div class="right">
<div @click="saveKeybind" class="actions">
<p>Save</p>
<div>
<img alt="" src="../public/cmd.svg" v-if="os === 'macos'" />
<img alt="" src="../public/ctrl.svg" v-if="os === 'linux' || os === 'windows'" />
<img alt="" src="../public/enter.svg" />
</div>
</div>
</div>
</div>
<div class="keybind-container">
<h2 class="title">Record a new Hotkey</h2>
<div
@blur="onBlur"
@focus="onFocus"
@keydown="onKeyDown"
class="keybind-input"
ref="keybindInput"
tabindex="0"
>
<span class="key" v-if="keybind.length === 0">Click here</span>
<template v-else>
<span
:key="index"
class="key"
:class="{ modifier: isModifier(key) }"
v-for="(key, index) in keybind"
>
{{ keyToDisplay(key) }}
</span>
</template>
</div>
</div>
</div>
<div class="bg">
<div class="back">
<img @click="router.push('/')" src="../public/back_arrow.svg" />
<p>Back</p>
</div>
<div class="bottom-bar">
<div class="left">
<img alt="" class="logo" src="../public/logo.png" width="18px" />
<p>Qopy</p>
</div>
<div class="right">
<div @click="saveKeybind" class="actions">
<p>Save</p>
<div>
<img alt="" src="../public/cmd.svg" v-if="os === 'macos'" />
<img alt="" src="../public/ctrl.svg" v-if="os === 'linux' || os === 'windows'" />
<img alt="" src="../public/enter.svg" />
</div>
</div>
</div>
</div>
<div class="keybind-container">
<h2 class="title">Record a new Hotkey</h2>
<div
@blur="onBlur"
@focus="onFocus"
@keydown="onKeyDown"
class="keybind-input"
ref="keybindInput"
tabindex="0"
>
<span class="key" v-if="keybind.length === 0">Click here</span>
<template v-else>
<span
:key="index"
class="key"
:class="{ modifier: isModifier(key) }"
v-for="(key, index) in keybind"
>
{{ keyToDisplay(key) }}
</span>
</template>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { invoke } from '@tauri-apps/api/core';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import { platform } from '@tauri-apps/plugin-os';
import { useRouter } from 'vue-router';
import { invoke } from "@tauri-apps/api/core";
import { platform } from "@tauri-apps/plugin-os";
import { onMounted, onUnmounted, reactive, ref } from "vue";
import { useRouter } from "vue-router";
const activeModifiers = reactive<Set<string>>(new Set());
const isKeybindInputFocused = ref(false);
const keybind = ref<string[]>([]);
const keybindInput = ref<HTMLElement | null>(null);
const lastBlurTime = ref(0);
const os = ref('');
const router = useRouter();
const activeModifiers = reactive<Set<string>>(new Set());
const isKeybindInputFocused = ref(false);
const keybind = ref<string[]>([]);
const keybindInput = ref<HTMLElement | null>(null);
const lastBlurTime = ref(0);
const os = ref("");
const router = useRouter();
const keyToDisplayMap: Record<string, string> = {
' ': 'Space',
Alt: 'Alt',
AltLeft: 'Alt L',
AltRight: 'Alt R',
ArrowDown: '↓',
ArrowLeft: '←',
ArrowRight: '→',
ArrowUp: '↑',
Control: 'Ctrl',
ControlLeft: 'Ctrl L',
ControlRight: 'Ctrl R',
Enter: '↵',
Meta: 'Meta',
MetaLeft: 'Meta L',
MetaRight: 'Meta R',
Shift: '⇧',
ShiftLeft: '⇧ L',
ShiftRight: '⇧ R',
};
const keyToDisplayMap: Record<string, string> = {
" ": "Space",
Alt: "Alt",
AltLeft: "Alt L",
AltRight: "Alt R",
ArrowDown: "↓",
ArrowLeft: "←",
ArrowRight: "→",
ArrowUp: "↑",
Control: "Ctrl",
ControlLeft: "Ctrl L",
ControlRight: "Ctrl R",
Enter: "↵",
Meta: "Meta",
MetaLeft: "Meta L",
MetaRight: "Meta R",
Shift: "⇧",
ShiftLeft: "⇧ L",
ShiftRight: "⇧ R",
};
const modifierKeySet = new Set([
'Alt', 'AltLeft', 'AltRight',
'Control', 'ControlLeft', 'ControlRight',
'Meta', 'MetaLeft', 'MetaRight',
'Shift', 'ShiftLeft', 'ShiftRight'
]);
const modifierKeySet = new Set([
"Alt",
"AltLeft",
"AltRight",
"Control",
"ControlLeft",
"ControlRight",
"Meta",
"MetaLeft",
"MetaRight",
"Shift",
"ShiftLeft",
"ShiftRight",
]);
const isModifier = (key: string): boolean => {
return modifierKeySet.has(key);
};
const isModifier = (key: string): boolean => {
return modifierKeySet.has(key);
};
const keyToDisplay = (key: string): string => {
return keyToDisplayMap[key] || key;
};
const keyToDisplay = (key: string): string => {
return keyToDisplayMap[key] || key;
};
const updateKeybind = () => {
const modifiers = Array.from(activeModifiers).sort();
const nonModifiers = keybind.value.filter(key => !isModifier(key));
keybind.value = [...modifiers, ...nonModifiers];
};
const updateKeybind = () => {
const modifiers = Array.from(activeModifiers).sort();
const nonModifiers = keybind.value.filter((key) => !isModifier(key));
keybind.value = [...modifiers, ...nonModifiers];
};
const onBlur = () => {
isKeybindInputFocused.value = false;
lastBlurTime.value = Date.now();
};
const onBlur = () => {
isKeybindInputFocused.value = false;
lastBlurTime.value = Date.now();
};
const onFocus = () => {
isKeybindInputFocused.value = true;
activeModifiers.clear();
keybind.value = [];
};
const onFocus = () => {
isKeybindInputFocused.value = true;
activeModifiers.clear();
keybind.value = [];
};
const onKeyDown = (event: KeyboardEvent) => {
event.preventDefault();
const key = event.code;
const onKeyDown = (event: KeyboardEvent) => {
event.preventDefault();
const key = event.code;
if (key === 'Escape') {
if (keybindInput.value) {
keybindInput.value.blur();
}
return;
}
if (key === "Escape") {
if (keybindInput.value) {
keybindInput.value.blur();
}
return;
}
if (isModifier(key)) {
activeModifiers.add(key);
} else if (!keybind.value.includes(key)) {
keybind.value = keybind.value.filter(k => isModifier(k));
keybind.value.push(key);
}
if (isModifier(key)) {
activeModifiers.add(key);
} else if (!keybind.value.includes(key)) {
keybind.value = keybind.value.filter((k) => isModifier(k));
keybind.value.push(key);
}
updateKeybind();
};
updateKeybind();
};
const saveKeybind = async () => {
console.log('New:', keybind.value);
const oldKeybind = await invoke<string[]>('get_keybind');
console.log('Old:', oldKeybind);
await invoke('save_keybind', { keybind: keybind.value });
};
const saveKeybind = async () => {
console.log("New:", keybind.value);
const oldKeybind = await invoke<string[]>("get_keybind");
console.log("Old:", oldKeybind);
await invoke("save_keybind", { keybind: keybind.value });
};
const handleGlobalKeyDown = (event: KeyboardEvent) => {
const now = Date.now();
if (
(os.value === 'macos'
? (event.code === 'MetaLeft' || event.code === 'MetaRight') && event.key === 'Enter'
: (event.code === 'ControlLeft' || event.code === 'ControlRight') && event.key === 'Enter') &&
!isKeybindInputFocused.value
) {
event.preventDefault();
saveKeybind();
} else if (
event.key === 'Escape' &&
!isKeybindInputFocused.value &&
now - lastBlurTime.value > 100
) {
event.preventDefault();
router.push('/');
}
};
const handleGlobalKeyDown = (event: KeyboardEvent) => {
const now = Date.now();
if (
(os.value === "macos"
? (event.code === "MetaLeft" || event.code === "MetaRight") && event.key === "Enter"
: (event.code === "ControlLeft" || event.code === "ControlRight") &&
event.key === "Enter") &&
!isKeybindInputFocused.value
) {
event.preventDefault();
saveKeybind();
} else if (
event.key === "Escape" &&
!isKeybindInputFocused.value &&
now - lastBlurTime.value > 100
) {
event.preventDefault();
router.push("/");
}
};
onMounted(() => {
os.value = platform();
window.addEventListener('keydown', handleGlobalKeyDown);
});
onMounted(() => {
os.value = platform();
window.addEventListener("keydown", handleGlobalKeyDown);
});
onUnmounted(() => {
window.removeEventListener('keydown', handleGlobalKeyDown);
});
onUnmounted(() => {
window.removeEventListener("keydown", handleGlobalKeyDown);
});
</script>
<style scoped lang="scss">
@use '~/assets/css/keybind.scss';
@use "~/assets/css/keybind.scss";
</style>

8
src-tauri/Cargo.lock generated
View file

@ -4508,9 +4508,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.132"
version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
dependencies = [
"itoa 1.0.11",
"memchr",
@ -6082,9 +6082,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.5.3"
version = "2.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada"
checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
dependencies = [
"form_urlencoded",
"idna",

View file

@ -10,7 +10,7 @@ rust-version = "1.70"
tauri-build = { version = "2.0.3", features = [] }
[dependencies]
tauri = { version = "2.0.1", features = [
tauri = { version = "2.1.1", features = [
"macos-private-api",
"tray-icon",
"image-png",
@ -27,17 +27,17 @@ tauri-plugin-global-shortcut = "2.0.1"
sqlx = { version = "0.8.2", features = ["runtime-tokio-native-tls", "sqlite"] }
serde = { version = "1.0.215", features = ["derive"] }
tokio = { version = "1.41.1", features = ["full"] }
serde_json = "1.0.132"
serde_json = "1.0.133"
rdev = "0.5.3"
rand = "0.8"
rand = "0.8.5"
base64 = "0.22.1"
image = "0.25.5"
reqwest = { version = "0.12.9", features = ["blocking"] }
url = "2.5.3"
url = "2.5.4"
regex = "1.11.1"
sha2 = "0.10.6"
lazy_static = "1.4.0"
time = "0.3"
sha2 = "0.10.8"
lazy_static = "1.5.0"
time = "0.3.36"
global-hotkey = "0.6.3"
[features]

View file

@ -1,34 +1,32 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "enables the default permissions",
"windows": [
"main"
],
"permissions": [
"core:path:default",
"core:event:default",
"core:window:default",
"core:webview:default",
"core:app:default",
"core:resources:default",
"core:image:default",
"core:menu:default",
"core:tray:default",
"sql:allow-load",
"sql:allow-select",
"sql:allow-execute",
"autostart:allow-enable",
"autostart:allow-disable",
"autostart:allow-is-enabled",
"os:allow-os-type",
"core:app:allow-app-hide",
"core:app:allow-app-show",
"core:window:allow-hide",
"core:window:allow-show",
"core:window:allow-set-focus",
"core:window:allow-is-focused",
"core:window:allow-is-visible",
"fs:allow-read"
]
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "enables the default permissions",
"windows": ["main"],
"permissions": [
"core:path:default",
"core:event:default",
"core:window:default",
"core:webview:default",
"core:app:default",
"core:resources:default",
"core:image:default",
"core:menu:default",
"core:tray:default",
"sql:allow-load",
"sql:allow-select",
"sql:allow-execute",
"autostart:allow-enable",
"autostart:allow-disable",
"autostart:allow-is-enabled",
"os:allow-os-type",
"core:app:allow-app-hide",
"core:app:allow-app-show",
"core:window:allow-hide",
"core:window:allow-show",
"core:window:allow-set-focus",
"core:window:allow-is-focused",
"core:window:allow-is-visible",
"fs:allow-read"
]
}

View file

@ -6,6 +6,7 @@
mod api;
mod utils;
use tauri::window::{Effect, EffectState, EffectsBuilder};
use tauri::Manager;
use tauri::WebviewUrl;
use tauri::WebviewWindow;
@ -45,7 +46,9 @@ fn main() {
.visible(false)
.decorations(false)
.transparent(true)
.always_on_top(false)
.always_on_top(true)
.content_protected(true)
.visible_on_all_workspaces(true)
.build()?
};
@ -68,6 +71,13 @@ fn main() {
api::updater::check_for_updates(app_handle).await;
});
main_window.set_effects(
EffectsBuilder::new()
.effect(Effect::Popover)
.state(EffectState::Active)
.build(),
)?;
Ok(())
})
.on_window_event(|_app, _event| {

View file

@ -1,60 +1,58 @@
{
"productName": "Qopy",
"version": "0.2.0",
"identifier": "net.pandadev.qopy",
"build": {
"frontendDist": "../dist",
"devUrl": "http://localhost:3000",
"beforeDevCommand": "pnpm nuxt dev",
"beforeBuildCommand": "pnpm nuxt generate"
},
"app": {
"windows": [
{
"title": "Qopy",
"titleBarStyle": "Overlay",
"fullscreen": false,
"resizable": false,
"height": 474,
"width": 750,
"minHeight": 474,
"maxHeight": 474,
"minWidth": 750,
"maxWidth": 750,
"decorations": false,
"center": true,
"shadow": false,
"transparent": true,
"skipTaskbar": true,
"alwaysOnTop": true
}
],
"security": {
"csp": null
},
"withGlobalTauri": true,
"macOSPrivateApi": true
},
"bundle": {
"createUpdaterArtifacts": true,
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"category": "DeveloperTool"
},
"plugins": {
"updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDExNDIzNjA1QjE0NjU1OTkKUldTWlZVYXhCVFpDRWNvNmt0UE5lQmZkblEyZGZiZ2tHelJvT2YvNVpLU1RIM1RKZFQrb2tzWWwK",
"endpoints": [
"https://qopy.pandadev.net/"
]
}
},
"$schema": "../node_modules/@tauri-apps/cli/schema.json"
"productName": "Qopy",
"version": "0.2.1",
"identifier": "net.pandadev.qopy",
"build": {
"frontendDist": "../dist",
"devUrl": "http://localhost:3000",
"beforeDevCommand": "pnpm nuxt dev",
"beforeBuildCommand": "pnpm nuxt generate"
},
"app": {
"windows": [
{
"title": "Qopy",
"titleBarStyle": "Overlay",
"fullscreen": false,
"resizable": false,
"height": 474,
"width": 750,
"minHeight": 474,
"maxHeight": 474,
"minWidth": 750,
"maxWidth": 750,
"decorations": false,
"center": true,
"shadow": false,
"transparent": true,
"skipTaskbar": true,
"alwaysOnTop": true
}
],
"security": {
"csp": null
},
"withGlobalTauri": true,
"macOSPrivateApi": true
},
"bundle": {
"createUpdaterArtifacts": true,
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"category": "DeveloperTool"
},
"plugins": {
"updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDExNDIzNjA1QjE0NjU1OTkKUldTWlZVYXhCVFpDRWNvNmt0UE5lQmZkblEyZGZiZ2tHelJvT2YvNVpLU1RIM1RKZFQrb2tzWWwK",
"endpoints": ["https://qopy.pandadev.net/"]
}
},
"$schema": "../node_modules/@tauri-apps/cli/schema.json"
}

View file

@ -1,4 +1,4 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}