Revert "style: formatting"

This reverts commit f2f554074b.
This commit is contained in:
PandaDEV 2024-11-23 15:09:16 +10:00
parent f2f554074b
commit d0b551b3fd
No known key found for this signature in database
GPG key ID: 13EFF9BAF70EE75C
22 changed files with 1171 additions and 1493 deletions

View file

@ -1,7 +1,7 @@
name: "\U0001F41E Bug report" name: "\U0001F41E Bug report"
description: Create a report to help me improve Qopy description: Create a report to help me improve Qopy
labels: [Bug] labels: [Bug]
assignees: assignees:
- 0PandaDEV - 0PandaDEV
body: body:
# #
@ -17,7 +17,7 @@ body:
description: A clear and concise description of what the bug is. description: A clear and concise description of what the bug is.
validations: validations:
required: true required: true
- type: textarea - type: textarea
id: reproduce id: reproduce
attributes: attributes:

View file

@ -1,7 +1,7 @@
name: "\U0001F4A1 Feature request" name: "\U0001F4A1 Feature request"
description: Suggest an idea for Qopy description: Suggest an idea for Qopy
labels: [Feature] labels: [Feature]
assignees: assignees:
- 0PandaDEV - 0PandaDEV
body: body:
# #

View file

@ -151,7 +151,7 @@ jobs:
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
name: updater-files-windows name: updater-files-windows
path: | path: |
src-tauri/target/release/bundle/msi/*.msi src-tauri/target/release/bundle/msi/*.msi
src-tauri/target/release/bundle/msi/*.msi.sig src-tauri/target/release/bundle/msi/*.msi.sig

View file

@ -1,214 +0,0 @@
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 }}

View file

@ -1,39 +0,0 @@
# 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

View file

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

View file

@ -1,13 +1,13 @@
# Get Started # Get Started
The hotkey for Qopy is Windows+V which is also the hotkey for the default clipboard manager to turn that off follow [this guide](https://github.com/0PandaDEV/Qopy/blob/main/GET_STARTED.md#disable-windowsv-for-default-clipboard-manager). The hotkey for Qopy is Windows+V which is also the hotkey for the default clipboard manager to turn that off follow [this guide](https://github.com/0PandaDEV/Qopy/blob/main/GET_STARTED.md#disable-windowsv-for-default-clipboard-manager).
All the data of Qopy is stored inside of a SQLite database. The location for the file differs for windows and linux. 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 | | Operating System | Path |
| ---------------- | ----------------------------------------------------- | |------------------|-------------------------------------------------------|
| Windows | `C:\Users\USERNAME\AppData\Roaming\net.pandadev.qopy` | | Windows | `C:\Users\USERNAME\AppData\Roaming\net.pandadev.qopy` |
| Linux | `` | | Linux | `` |
## Disable Windows+V for default clipboard manager ## Disable Windows+V for default clipboard manager

View file

@ -60,7 +60,6 @@ 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. 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 ## 🚧 Roadmap
- [ ] [Setup guide](https://github.com/0PandaDEV/Qopy/blob/main/GET_STARTED.md) - [ ] [Setup guide](https://github.com/0PandaDEV/Qopy/blob/main/GET_STARTED.md)
- [ ] Settings https://github.com/0PandaDEV/Qopy/issues/2 - [ ] Settings https://github.com/0PandaDEV/Qopy/issues/2
- [ ] Metadata for copied items https://github.com/0PandaDEV/Qopy/issues/5 - [ ] Metadata for copied items https://github.com/0PandaDEV/Qopy/issues/5
@ -73,7 +72,6 @@ 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> <sup>If you have ideas for features to include, please write a feature request [here](https://github.com/0pandadev/Qopy/issues).</sup>
## 📦 Preview ## 📦 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/18e1f9e3-414c-46e2-9c51-61c6e63a06d2"/>
<img width="800px" src="https://github.com/user-attachments/assets/46ec4672-f156-4426-a2cb-3a40d00dbcd6"/> <img width="800px" src="https://github.com/user-attachments/assets/46ec4672-f156-4426-a2cb-3a40d00dbcd6"/>
@ -113,7 +111,7 @@ pnpm build
> \[!NOTE] > \[!NOTE]
> >
> Don't worry, it will fail at the end because it can not detect a Private key, but the installer files will be generated regardless of that. > Don't worry, it will fail at the end because it can not detect a Private key, but the installer files will be generated regardless of that.
> >
> You can find them in `src-tauri/target/release/bundle`. > You can find them in `src-tauri/target/release/bundle`.
## 📝 License ## 📝 License

48
app.vue
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

8
src-tauri/Cargo.lock generated
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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