mirror of
https://gitlab.com/vyla-entertainment/home.git
synced 2026-11-14 22:27:20 -05:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 33e285953c | |||
| f46869f967 | |||
| b19e6b21c9 | |||
| c8ea2598b9 | |||
| e3257b8a3a | |||
| fbb5a4437d | |||
| dbaab9a00e | |||
| fc49bb93a7 | |||
| 9229f0c2dd | |||
| 843abf7df4 | |||
| 27fda0430b | |||
| 8b49d679bd | |||
| 62883b3180 | |||
| 3c6ae0125b | |||
| be0810ea6d | |||
| dff55060e7 | |||
| df767b5ffc | |||
| 1b70c6784a | |||
| e25e1c93f9 | |||
| 4c708ad97c | |||
| b81a4e044b | |||
| f6aa2daa01 | |||
| e03eb38adc | |||
| 2b690b47c1 | |||
| dffbdb92a5 | |||
| 45d6515f2e | |||
| a3e6a278fe | |||
| 7ffc20ee48 | |||
| ddf3abb314 | |||
| ec50c4e07f |
1
DOCUEMENTATION/CLEAR.bash
Normal file
1
DOCUEMENTATION/CLEAR.bash
Normal file
@@ -0,0 +1 @@
|
|||||||
|
bash -c 'pkill -9 -x node 2>/dev/null; pkill -9 -x "Vyla Home" 2>/dev/null; pkill -9 -x "vyla-home" 2>/dev/null; rm -rf "$HOME/Library/Application Support/com.vyla.home" "$HOME/Library/Application Support/vyla-home" "$HOME/Library/Application Support/Vyla Home" "$HOME/Library/Caches/com.vyla.home" "$HOME/Library/Caches/vyla-home" "$HOME/Library/Caches/Vyla Home" "$HOME/Library/WebKit/com.vyla.home" "$HOME/Library/WebKit/vyla-home" "$HOME/Library/WebKit/Vyla Home" "$HOME/Library/Logs/Vyla Home" "$HOME/Library/Preferences/com.vyla.home.plist" "$HOME/.vyla-home" "/Applications/Vyla Home.app" "/Applications/vyla-home.app" "$HOME/Applications/Vyla Home.app" "$HOME/Applications/vyla-home.app" "src-tauri/target" "dist-build" "temp-validation-extract" "dist" "frontend" "player" "auth-proxy" "stream-api" "logs" "*.log" "download-temp.zip" "update-payload.zip" "manifest.json" "validation-report.json" "config/encrypted-credentials.json" "config/credentials.json"; echo "Vyla Home cleanup complete."'
|
||||||
@@ -22,8 +22,8 @@ const clonedRepos = new Set();
|
|||||||
|
|
||||||
function clonePrivateRepo(repoConfig, targetDir) {
|
function clonePrivateRepo(repoConfig, targetDir) {
|
||||||
if (fs.existsSync(targetDir)) {
|
if (fs.existsSync(targetDir)) {
|
||||||
console.log(`[DEV] ${repoConfig.name} already exists locally. Skipping clone to use local changes.`);
|
console.log(`Removing stale ${repoConfig.name} before fresh clone...`);
|
||||||
return;
|
fs.rmSync(targetDir, { recursive: true, force: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = process.env.GITLAB_TOKEN || process.env.VYLA_GITLAB_TOKEN;
|
const token = process.env.GITLAB_TOKEN || process.env.VYLA_GITLAB_TOKEN;
|
||||||
|
|||||||
@@ -27,6 +27,20 @@ workflows:
|
|||||||
export PATH="$HOME/.cargo/bin:$PATH"
|
export PATH="$HOME/.cargo/bin:$PATH"
|
||||||
PACKAGE_VERSION=$(node -p "require('./package.json').version")
|
PACKAGE_VERSION=$(node -p "require('./package.json').version")
|
||||||
node release.js --installer --tag="v$PACKAGE_VERSION"
|
node release.js --installer --tag="v$PACKAGE_VERSION"
|
||||||
|
- name: Verify bundled node permissions
|
||||||
|
script: |
|
||||||
|
if [ -f "bin/node" ]; then
|
||||||
|
chmod +x bin/node
|
||||||
|
xattr -cr bin/node || true
|
||||||
|
ls -la bin/node
|
||||||
|
file bin/node
|
||||||
|
fi
|
||||||
|
APP_NODE=$(find src-tauri/target/release/bundle -name "node" -path "*bin*" 2>/dev/null | head -1)
|
||||||
|
if [ -n "$APP_NODE" ]; then
|
||||||
|
chmod +x "$APP_NODE"
|
||||||
|
xattr -cr "$APP_NODE" || true
|
||||||
|
ls -la "$APP_NODE"
|
||||||
|
fi
|
||||||
artifacts:
|
artifacts:
|
||||||
- src-tauri/target/release/bundle/dmg/*.dmg
|
- src-tauri/target/release/bundle/dmg/*.dmg
|
||||||
- src-tauri/target/release/bundle/macos/*.app
|
- src-tauri/target/release/bundle/macos/*.app
|
||||||
15
main.js
15
main.js
@@ -6,10 +6,19 @@ const ServiceManager = require('./service-manager');
|
|||||||
const Patcher = require('./patcher');
|
const Patcher = require('./patcher');
|
||||||
const UpdateClient = require('./update-client');
|
const UpdateClient = require('./update-client');
|
||||||
|
|
||||||
const defaultAppData = path.join(os.homedir(), 'AppData', 'Roaming', 'vyla-home', 'vyla-home-files');
|
function getDefaultAppData() {
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
return path.join(os.homedir(), 'Library', 'Application Support', 'vyla-home', 'vyla-home-files');
|
||||||
|
}
|
||||||
|
if (process.platform === 'linux') {
|
||||||
|
return path.join(os.homedir(), '.local', 'share', 'vyla-home', 'vyla-home-files');
|
||||||
|
}
|
||||||
|
return path.join(os.homedir(), 'AppData', 'Roaming', 'vyla-home', 'vyla-home-files');
|
||||||
|
}
|
||||||
|
|
||||||
const APPDATA_DIR = (process.env.APPDATA_PATH && !process.env.APPDATA_PATH.includes('com.vyla.home'))
|
const APPDATA_DIR = (process.env.APPDATA_PATH && !process.env.APPDATA_PATH.includes('com.vyla.home'))
|
||||||
? process.env.APPDATA_PATH
|
? process.env.APPDATA_PATH
|
||||||
: defaultAppData;
|
: getDefaultAppData();
|
||||||
|
|
||||||
const LOGS_DIR = path.join(APPDATA_DIR, 'logs');
|
const LOGS_DIR = path.join(APPDATA_DIR, 'logs');
|
||||||
try { fs.mkdirSync(LOGS_DIR, { recursive: true }); } catch (e) { }
|
try { fs.mkdirSync(LOGS_DIR, { recursive: true }); } catch (e) { }
|
||||||
@@ -401,7 +410,7 @@ async function start() {
|
|||||||
expressServer = expressApp.listen(FRONTEND_PORT, '127.0.0.1', () => {
|
expressServer = expressApp.listen(FRONTEND_PORT, '127.0.0.1', () => {
|
||||||
sendToTauri('status', { message: 'All backend services running and healthy.' });
|
sendToTauri('status', { message: 'All backend services running and healthy.' });
|
||||||
debugLog("Frontend Express running on 4890. Sending READY to Tauri.");
|
debugLog("Frontend Express running on 4890. Sending READY to Tauri.");
|
||||||
sendToTauri('ready', { url: `http://localhost:${FRONTEND_PORT}` });
|
sendToTauri('ready', { url: `http://127.0.0.1:${FRONTEND_PORT}` });
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vyla-home",
|
"name": "vyla-home",
|
||||||
"version": "1.1.13",
|
"version": "1.1.28",
|
||||||
"description": "Vyla Home Desktop App Launcher",
|
"description": "Vyla Home Desktop App Launcher",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
11
release.js
11
release.js
@@ -295,11 +295,18 @@ function ensureBundledNode() {
|
|||||||
try {
|
try {
|
||||||
execSync(`tar -xzf node.tar.gz ${tarName}/bin/node`, { cwd: binDir });
|
execSync(`tar -xzf node.tar.gz ${tarName}/bin/node`, { cwd: binDir });
|
||||||
|
|
||||||
fs.renameSync(path.join(binDir, tarName, 'bin', 'node'), path.join(binDir, 'node'));
|
const extractedNode = path.join(binDir, tarName, 'bin', 'node');
|
||||||
|
const finalNode = path.join(binDir, 'node');
|
||||||
|
|
||||||
|
fs.renameSync(extractedNode, finalNode);
|
||||||
fs.rmSync(path.join(binDir, tarName), { recursive: true, force: true });
|
fs.rmSync(path.join(binDir, tarName), { recursive: true, force: true });
|
||||||
fs.unlinkSync(tarPath);
|
fs.unlinkSync(tarPath);
|
||||||
|
|
||||||
execSync(`chmod +x node`, { cwd: binDir });
|
fs.chmodSync(finalNode, 0o755);
|
||||||
|
|
||||||
|
try {
|
||||||
|
execSync(`xattr -d com.apple.quarantine "${finalNode}"`);
|
||||||
|
} catch (_) { }
|
||||||
|
|
||||||
fs.writeFileSync(versionMarker, nodeVersion, 'utf8');
|
fs.writeFileSync(versionMarker, nodeVersion, 'utf8');
|
||||||
resolve();
|
resolve();
|
||||||
|
|||||||
69
src-tauri/Cargo.lock
generated
69
src-tauri/Cargo.lock
generated
@@ -270,7 +270,7 @@ version = "0.6.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
|
checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -762,7 +762,7 @@ dependencies = [
|
|||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
"block2",
|
"block2",
|
||||||
"libc",
|
"libc",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2079,7 +2079,7 @@ dependencies = [
|
|||||||
"dpi",
|
"dpi",
|
||||||
"gtk",
|
"gtk",
|
||||||
"keyboard-types",
|
"keyboard-types",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-app-kit",
|
"objc2-app-kit",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
@@ -2157,6 +2157,22 @@ dependencies = [
|
|||||||
"syn 2.0.119",
|
"syn 2.0.119",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc-sys"
|
||||||
|
version = "0.3.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
|
||||||
|
dependencies = [
|
||||||
|
"objc-sys",
|
||||||
|
"objc2-encode",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2"
|
name = "objc2"
|
||||||
version = "0.6.4"
|
version = "0.6.4"
|
||||||
@@ -2175,7 +2191,7 @@ checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
"block2",
|
"block2",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
]
|
]
|
||||||
@@ -2187,7 +2203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c"
|
checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2197,7 +2213,7 @@ version = "0.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa"
|
checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2209,7 +2225,7 @@ checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
"dispatch2",
|
"dispatch2",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2220,7 +2236,7 @@ checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
"dispatch2",
|
"dispatch2",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-io-surface",
|
"objc2-io-surface",
|
||||||
]
|
]
|
||||||
@@ -2231,7 +2247,7 @@ version = "0.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006"
|
checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2241,7 +2257,7 @@ version = "0.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009"
|
checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2252,7 +2268,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d"
|
checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-core-graphics",
|
"objc2-core-graphics",
|
||||||
]
|
]
|
||||||
@@ -2280,7 +2296,7 @@ checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
"block2",
|
"block2",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2291,7 +2307,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d"
|
checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2302,7 +2318,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f"
|
checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
]
|
]
|
||||||
@@ -2315,7 +2331,7 @@ checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
"block2",
|
"block2",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-cloud-kit",
|
"objc2-cloud-kit",
|
||||||
"objc2-core-data",
|
"objc2-core-data",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
@@ -2334,7 +2350,7 @@ version = "0.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e"
|
checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2346,7 +2362,7 @@ checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.1",
|
"bitflags 2.13.1",
|
||||||
"block2",
|
"block2",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-app-kit",
|
"objc2-app-kit",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
@@ -3211,7 +3227,7 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"ndk",
|
"ndk",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-core-graphics",
|
"objc2-core-graphics",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
@@ -3385,7 +3401,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"ndk",
|
"ndk",
|
||||||
"ndk-sys",
|
"ndk-sys",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-app-kit",
|
"objc2-app-kit",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
"objc2-ui-kit",
|
"objc2-ui-kit",
|
||||||
@@ -3441,7 +3457,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"mime",
|
"mime",
|
||||||
"muda",
|
"muda",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-app-kit",
|
"objc2-app-kit",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
"objc2-ui-kit",
|
"objc2-ui-kit",
|
||||||
@@ -3612,7 +3628,7 @@ dependencies = [
|
|||||||
"gtk",
|
"gtk",
|
||||||
"http",
|
"http",
|
||||||
"jni",
|
"jni",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-ui-kit",
|
"objc2-ui-kit",
|
||||||
"objc2-web-kit",
|
"objc2-web-kit",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
@@ -3636,7 +3652,7 @@ dependencies = [
|
|||||||
"http",
|
"http",
|
||||||
"jni",
|
"jni",
|
||||||
"log",
|
"log",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-app-kit",
|
"objc2-app-kit",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
@@ -4051,7 +4067,7 @@ dependencies = [
|
|||||||
"dirs",
|
"dirs",
|
||||||
"libappindicator",
|
"libappindicator",
|
||||||
"muda",
|
"muda",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-app-kit",
|
"objc2-app-kit",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-core-graphics",
|
"objc2-core-graphics",
|
||||||
@@ -4222,9 +4238,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vyla-home"
|
name = "vyla-home"
|
||||||
version = "1.1.13"
|
version = "1.1.28"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
|
"objc2 0.5.2",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
@@ -4475,7 +4492,7 @@ version = "0.6.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c"
|
checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-app-kit",
|
"objc2-app-kit",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
@@ -4930,7 +4947,7 @@ dependencies = [
|
|||||||
"jni",
|
"jni",
|
||||||
"libc",
|
"libc",
|
||||||
"ndk",
|
"ndk",
|
||||||
"objc2",
|
"objc2 0.6.4",
|
||||||
"objc2-app-kit",
|
"objc2-app-kit",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vyla-home"
|
name = "vyla-home"
|
||||||
version = "1.1.13"
|
version = "1.1.28"
|
||||||
description = "Vyla Home Desktop App Launcher"
|
description = "Vyla Home Desktop App Launcher"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
@@ -16,6 +16,9 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
objc2 = "0.5"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
lto = true
|
lto = true
|
||||||
|
|||||||
13
src-tauri/Info.plist
Normal file
13
src-tauri/Info.plist
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSAllowsLocalNetworking</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -58,11 +58,23 @@ fn kill_child_process(child: &mut Child) {
|
|||||||
|
|
||||||
fn find_node_binary(app: &tauri::App) -> Option<String> {
|
fn find_node_binary(app: &tauri::App) -> Option<String> {
|
||||||
if let Ok(resource_dir) = app.path().resource_dir() {
|
if let Ok(resource_dir) = app.path().resource_dir() {
|
||||||
|
#[cfg(windows)]
|
||||||
let candidates = [
|
let candidates = [
|
||||||
resource_dir.join("bin").join("node.exe"),
|
resource_dir.join("bin").join("node.exe"),
|
||||||
resource_dir.join("node.exe"),
|
resource_dir.join("node.exe"),
|
||||||
resource_dir.join("_up_").join("bin").join("node.exe"),
|
resource_dir.join("_up_").join("bin").join("node.exe"),
|
||||||
resource_dir.join("_up_").join("node.exe"),
|
resource_dir.join("_up_").join("node.exe"),
|
||||||
|
resource_dir.join("up").join("bin").join("node.exe"),
|
||||||
|
resource_dir.join("up").join("node.exe"),
|
||||||
|
];
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
let candidates = [
|
||||||
|
resource_dir.join("bin").join("node"),
|
||||||
|
resource_dir.join("node"),
|
||||||
|
resource_dir.join("_up_").join("bin").join("node"),
|
||||||
|
resource_dir.join("_up_").join("node"),
|
||||||
|
resource_dir.join("up").join("bin").join("node"),
|
||||||
|
resource_dir.join("up").join("node"),
|
||||||
];
|
];
|
||||||
for candidate in candidates {
|
for candidate in candidates {
|
||||||
if candidate.exists() {
|
if candidate.exists() {
|
||||||
@@ -75,9 +87,13 @@ fn find_node_binary(app: &tauri::App) -> Option<String> {
|
|||||||
if let Some(parent) = exe_path.parent() {
|
if let Some(parent) = exe_path.parent() {
|
||||||
let candidates = [
|
let candidates = [
|
||||||
parent.join("bin").join("node.exe"),
|
parent.join("bin").join("node.exe"),
|
||||||
|
parent.join("bin").join("node"),
|
||||||
parent.join("node.exe"),
|
parent.join("node.exe"),
|
||||||
|
parent.join("node"),
|
||||||
parent.join("resources").join("bin").join("node.exe"),
|
parent.join("resources").join("bin").join("node.exe"),
|
||||||
|
parent.join("resources").join("bin").join("node"),
|
||||||
parent.join("resources").join("node.exe"),
|
parent.join("resources").join("node.exe"),
|
||||||
|
parent.join("resources").join("node"),
|
||||||
];
|
];
|
||||||
for candidate in candidates {
|
for candidate in candidates {
|
||||||
if candidate.exists() {
|
if candidate.exists() {
|
||||||
@@ -89,9 +105,13 @@ fn find_node_binary(app: &tauri::App) -> Option<String> {
|
|||||||
|
|
||||||
if let Ok(path_var) = std::env::var("PATH") {
|
if let Ok(path_var) = std::env::var("PATH") {
|
||||||
for p in std::env::split_paths(&path_var) {
|
for p in std::env::split_paths(&path_var) {
|
||||||
let candidate = p.join("node.exe");
|
let node_exe = p.join("node.exe");
|
||||||
if candidate.exists() {
|
if node_exe.exists() {
|
||||||
return Some(clean_path(&candidate));
|
return Some(clean_path(&node_exe));
|
||||||
|
}
|
||||||
|
let node = p.join("node");
|
||||||
|
if node.exists() {
|
||||||
|
return Some(clean_path(&node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,6 +140,22 @@ fn find_node_binary(app: &tauri::App) -> Option<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
{
|
||||||
|
let default_paths = [
|
||||||
|
"/usr/local/bin/node",
|
||||||
|
"/usr/bin/node",
|
||||||
|
"/opt/homebrew/bin/node",
|
||||||
|
"/opt/local/bin/node",
|
||||||
|
];
|
||||||
|
for path in default_paths {
|
||||||
|
let candidate = std::path::Path::new(path);
|
||||||
|
if candidate.exists() {
|
||||||
|
return Some(clean_path(candidate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +164,7 @@ fn resolve_script_and_root(app: &tauri::App) -> (String, String) {
|
|||||||
let candidates = vec![
|
let candidates = vec![
|
||||||
resource_dir.join("main.js"),
|
resource_dir.join("main.js"),
|
||||||
resource_dir.join("_up_").join("main.js"),
|
resource_dir.join("_up_").join("main.js"),
|
||||||
|
resource_dir.join("up").join("main.js"),
|
||||||
];
|
];
|
||||||
|
|
||||||
for candidate in candidates {
|
for candidate in candidates {
|
||||||
@@ -466,9 +503,9 @@ fn open_new_window(app: tauri::AppHandle, url: String) -> Result<(), String> {
|
|||||||
let final_url = if url.starts_with("http") || url.starts_with("tauri://") {
|
let final_url = if url.starts_with("http") || url.starts_with("tauri://") {
|
||||||
url.clone()
|
url.clone()
|
||||||
} else if url.starts_with('/') {
|
} else if url.starts_with('/') {
|
||||||
format!("http://localhost:4890{}", url)
|
format!("http://127.0.0.1:4890{}", url)
|
||||||
} else {
|
} else {
|
||||||
format!("http://localhost:4890/{}", url)
|
format!("http://127.0.0.1:4890/{}", url)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(window) = app.get_webview_window("main") {
|
if let Some(window) = app.get_webview_window("main") {
|
||||||
@@ -561,10 +598,23 @@ fn main() {
|
|||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
debug_log("Tauri setup started");
|
debug_log("Tauri setup started");
|
||||||
let app_data = app.path().app_data_dir().unwrap_or_default();
|
let app_data = app.path().app_data_dir().unwrap_or_default();
|
||||||
let app_data_str = clean_path(&app_data);
|
|
||||||
|
|
||||||
let vyla_files = if let Ok(appdata_env) = std::env::var("APPDATA") {
|
let vyla_files = if let Ok(appdata_env) = std::env::var("APPDATA") {
|
||||||
std::path::PathBuf::from(appdata_env).join("vyla-home").join("vyla-home-files")
|
std::path::PathBuf::from(appdata_env)
|
||||||
|
.join("vyla-home")
|
||||||
|
.join("vyla-home-files")
|
||||||
|
} else if let Ok(home) = std::env::var("HOME") {
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
let base = std::path::PathBuf::from(&home)
|
||||||
|
.join("Library")
|
||||||
|
.join("Application Support");
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
let base = std::path::PathBuf::from(&home)
|
||||||
|
.join(".local")
|
||||||
|
.join("share");
|
||||||
|
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
||||||
|
let base = app_data.clone();
|
||||||
|
base.join("vyla-home").join("vyla-home-files")
|
||||||
} else {
|
} else {
|
||||||
app_data.join("vyla-home-files")
|
app_data.join("vyla-home-files")
|
||||||
};
|
};
|
||||||
@@ -603,29 +653,46 @@ fn main() {
|
|||||||
.inner_size(1280.0, 800.0)
|
.inner_size(1280.0, 800.0)
|
||||||
.decorations(false)
|
.decorations(false)
|
||||||
.resizable(true)
|
.resizable(true)
|
||||||
.devtools(cfg!(debug_assertions))
|
.devtools(true)
|
||||||
.initialization_script("window.__VYLA_WINDOW_LABEL = 'main';")
|
.initialization_script("window.__VYLA_WINDOW_LABEL = 'main';")
|
||||||
.initialization_script(LINK_HANDLER_SCRIPT)
|
.initialization_script(LINK_HANDLER_SCRIPT)
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
{
|
||||||
|
use objc2::msg_send;
|
||||||
|
use objc2::runtime::AnyObject;
|
||||||
|
let _ = window.with_webview(|webview| unsafe {
|
||||||
|
let wk_webview = webview.inner() as *mut AnyObject;
|
||||||
|
let config: *mut AnyObject = msg_send![wk_webview, configuration];
|
||||||
|
let _: () = msg_send![config, setUpgradeKnownHostsToHTTPS: false];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let (main_js, root_dir) = resolve_script_and_root(app);
|
let (main_js, root_dir) = resolve_script_and_root(app);
|
||||||
|
debug_log("Searching for node binary...");
|
||||||
let node_bin = match find_node_binary(app) {
|
let node_bin = match find_node_binary(app) {
|
||||||
Some(bin) => bin,
|
Some(bin) => {
|
||||||
|
debug_log(&format!("Found node binary: {}", bin));
|
||||||
|
bin
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
let _ = window.emit(
|
debug_log("FATAL: No node binary found in bundle or PATH.");
|
||||||
"error",
|
std::thread::sleep(std::time::Duration::from_millis(600));
|
||||||
serde_json::json!({
|
let _ = window.eval("document.getElementById('status-message').textContent='Error: Node runtime missing. Please reinstall.';");
|
||||||
"message": "Node.js runtime not found. Please ensure Node.js is installed or bundled correctly."
|
let _ = window.eval("var b=document.getElementById('debug-log-box');b.style.display='block';b.textContent='Node binary not found. bin/node missing from app bundle or not executable.';");
|
||||||
}),
|
|
||||||
);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let vyla_files_str = clean_path(&vyla_files);
|
||||||
|
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(400));
|
||||||
|
|
||||||
let mut cmd = Command::new(&node_bin);
|
let mut cmd = Command::new(&node_bin);
|
||||||
cmd.arg(&main_js)
|
cmd.arg(&main_js)
|
||||||
.current_dir(&root_dir)
|
.current_dir(&root_dir)
|
||||||
.env("APPDATA_PATH", &app_data_str)
|
.env("APPDATA_PATH", &vyla_files_str)
|
||||||
.env("NODE_EXE", &node_bin)
|
.env("NODE_EXE", &node_bin)
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
@@ -802,9 +869,15 @@ fn main() {
|
|||||||
window_label
|
window_label
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else if msg.event == "ready" {
|
||||||
let _ = w.emit(&msg.event, msg.data.clone());
|
if let Some(url_str) = msg.data.get("url").and_then(|u| u.as_str()) {
|
||||||
}
|
if let Ok(url_parsed) = url_str.parse::<tauri::Url>() {
|
||||||
|
let _ = w.navigate(url_parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let _ = w.emit(&msg.event, msg.data.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -817,12 +890,12 @@ fn main() {
|
|||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug_log(&format!("Failed to spawn node: {}", e));
|
debug_log(&format!("Failed to spawn node: {}", e));
|
||||||
let _ = window.emit(
|
let emsg = format!("Failed to spawn node: {}", e);
|
||||||
"error",
|
let js = format!(
|
||||||
serde_json::json!({
|
"document.getElementById('status-message').textContent='Spawn Error';var b=document.getElementById('debug-log-box');b.style.display='block';b.textContent={};",
|
||||||
"message": format!("Failed to launch backend runtime: {}", e)
|
serde_json::to_string(&emsg).unwrap_or_default()
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
let _ = window.eval(&js);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Vyla Home",
|
"productName": "Vyla Home",
|
||||||
"version": "1.1.13",
|
"version": "1.1.28",
|
||||||
"identifier": "com.vyla.home",
|
"identifier": "com.vyla.home",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../ui"
|
"frontendDist": "../ui"
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
"app": {
|
"app": {
|
||||||
"withGlobalTauri": true,
|
"withGlobalTauri": true,
|
||||||
"security": {
|
"security": {
|
||||||
"csp": null
|
"csp": "default-src 'self' http://localhost:4890 http://127.0.0.1:4890; script-src 'self' 'unsafe-inline' 'unsafe-eval' http://localhost:4890 http://127.0.0.1:4890 https://esm.sh; style-src 'self' 'unsafe-inline' http://localhost:4890 http://127.0.0.1:4890; img-src 'self' data: https: http://localhost:4890 http://127.0.0.1:4890; font-src 'self' data: http://localhost:4890 http://127.0.0.1:4890; connect-src 'self' http://localhost: http://127.0.0.1:"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
@@ -22,6 +22,10 @@
|
|||||||
"icons/icon.icns",
|
"icons/icon.icns",
|
||||||
"icons/icon.ico"
|
"icons/icon.ico"
|
||||||
],
|
],
|
||||||
|
"macOS": {
|
||||||
|
"exceptionDomain": "localhost",
|
||||||
|
"infoPlist": "Info.plist"
|
||||||
|
},
|
||||||
"windows": {
|
"windows": {
|
||||||
"webviewInstallMode": {
|
"webviewInstallMode": {
|
||||||
"type": "downloadBootstrapper"
|
"type": "downloadBootstrapper"
|
||||||
|
|||||||
274
ui/index.html
274
ui/index.html
@@ -271,61 +271,66 @@
|
|||||||
console.warn("OGL Shader background failed to load (offline):", err);
|
console.warn("OGL Shader background failed to load (offline):", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.__OGL_LOADED__) {
|
window.dispatchEvent(new Event('ogl-ready'));
|
||||||
document.body.style.background = "radial-gradient(circle at 80% 20%, #1e1b4b 0%, #050505 70%)";
|
</script>
|
||||||
} else {
|
|
||||||
const { Renderer, Program, Triangle, Mesh } = window.__OGL_LOADED__;
|
|
||||||
const rayContainer = document.getElementById("side-rays");
|
|
||||||
const settings = {
|
|
||||||
speed: 2.5,
|
|
||||||
rayColor1: "#EAB308",
|
|
||||||
rayColor2: "#96c8ff",
|
|
||||||
intensity: 2,
|
|
||||||
spread: 2,
|
|
||||||
origin: "top-right",
|
|
||||||
tilt: 0,
|
|
||||||
saturation: 1.5,
|
|
||||||
blend: 0.75,
|
|
||||||
falloff: 1.6,
|
|
||||||
opacity: 1
|
|
||||||
};
|
|
||||||
|
|
||||||
function hexToRgb(hex) {
|
<script>
|
||||||
const match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
window.addEventListener('ogl-ready', () => {
|
||||||
if (!match) return [1, 1, 1];
|
if (!window.__OGL_LOADED__) {
|
||||||
return [
|
document.body.style.background = "radial-gradient(circle at 80% 20%, #1e1b4b 0%, #050505 70%)";
|
||||||
parseInt(match[1], 16) / 255,
|
} else {
|
||||||
parseInt(match[2], 16) / 255,
|
const { Renderer, Program, Triangle, Mesh } = window.__OGL_LOADED__;
|
||||||
parseInt(match[3], 16) / 255
|
const rayContainer = document.getElementById("side-rays");
|
||||||
];
|
const settings = {
|
||||||
}
|
speed: 2.5,
|
||||||
|
rayColor1: "#EAB308",
|
||||||
|
rayColor2: "#96c8ff",
|
||||||
|
intensity: 2,
|
||||||
|
spread: 2,
|
||||||
|
origin: "top-right",
|
||||||
|
tilt: 0,
|
||||||
|
saturation: 1.5,
|
||||||
|
blend: 0.75,
|
||||||
|
falloff: 1.6,
|
||||||
|
opacity: 1
|
||||||
|
};
|
||||||
|
|
||||||
function originToFlip(origin) {
|
function hexToRgb(hex) {
|
||||||
switch (origin) {
|
const match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||||
case "top-left": return [1, 0];
|
if (!match) return [1, 1, 1];
|
||||||
case "bottom-right": return [0, 1];
|
return [
|
||||||
case "bottom-left": return [1, 1];
|
parseInt(match[1], 16) / 255,
|
||||||
default: return [0, 0];
|
parseInt(match[2], 16) / 255,
|
||||||
|
parseInt(match[3], 16) / 255
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const renderer = new Renderer({
|
function originToFlip(origin) {
|
||||||
dpr: Math.min(window.devicePixelRatio, 2),
|
switch (origin) {
|
||||||
alpha: true
|
case "top-left": return [1, 0];
|
||||||
});
|
case "bottom-right": return [0, 1];
|
||||||
const gl = renderer.gl;
|
case "bottom-left": return [1, 1];
|
||||||
gl.canvas.style.width = "100%";
|
default: return [0, 0];
|
||||||
gl.canvas.style.height = "100%";
|
}
|
||||||
rayContainer.appendChild(gl.canvas);
|
}
|
||||||
|
|
||||||
const vertexShader = `
|
const renderer = new Renderer({
|
||||||
|
dpr: Math.min(window.devicePixelRatio, 2),
|
||||||
|
alpha: true
|
||||||
|
});
|
||||||
|
const gl = renderer.gl;
|
||||||
|
gl.canvas.style.width = "100%";
|
||||||
|
gl.canvas.style.height = "100%";
|
||||||
|
rayContainer.appendChild(gl.canvas);
|
||||||
|
|
||||||
|
const vertexShader = `
|
||||||
attribute vec2 position;
|
attribute vec2 position;
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(position, 0.0, 1.0);
|
gl_Position = vec4(position, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const fragmentShader = `
|
const fragmentShader = `
|
||||||
precision highp float;
|
precision highp float;
|
||||||
uniform float iTime;
|
uniform float iTime;
|
||||||
uniform vec2 iResolution;
|
uniform vec2 iResolution;
|
||||||
@@ -386,77 +391,77 @@ void main() {
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const [flipX, flipY] = originToFlip(settings.origin);
|
const [flipX, flipY] = originToFlip(settings.origin);
|
||||||
const uniforms = {
|
const uniforms = {
|
||||||
iTime: { value: 0 },
|
iTime: { value: 0 },
|
||||||
iResolution: { value: [1, 1] },
|
iResolution: { value: [1, 1] },
|
||||||
iSpeed: { value: settings.speed },
|
iSpeed: { value: settings.speed },
|
||||||
iRayColor1: { value: hexToRgb(settings.rayColor1) },
|
iRayColor1: { value: hexToRgb(settings.rayColor1) },
|
||||||
iRayColor2: { value: hexToRgb(settings.rayColor2) },
|
iRayColor2: { value: hexToRgb(settings.rayColor2) },
|
||||||
iIntensity: { value: settings.intensity },
|
iIntensity: { value: settings.intensity },
|
||||||
iSpread: { value: settings.spread },
|
iSpread: { value: settings.spread },
|
||||||
iFlipX: { value: flipX },
|
iFlipX: { value: flipX },
|
||||||
iFlipY: { value: flipY },
|
iFlipY: { value: flipY },
|
||||||
iTilt: { value: settings.tilt },
|
iTilt: { value: settings.tilt },
|
||||||
iSaturation: { value: settings.saturation },
|
iSaturation: { value: settings.saturation },
|
||||||
iBlend: { value: settings.blend },
|
iBlend: { value: settings.blend },
|
||||||
iFalloff: { value: settings.falloff },
|
iFalloff: { value: settings.falloff },
|
||||||
iOpacity: { value: settings.opacity }
|
iOpacity: { value: settings.opacity }
|
||||||
};
|
};
|
||||||
|
|
||||||
const geometry = new Triangle(gl);
|
const geometry = new Triangle(gl);
|
||||||
const program = new Program(gl, { vertex: vertexShader, fragment: fragmentShader, uniforms });
|
const program = new Program(gl, { vertex: vertexShader, fragment: fragmentShader, uniforms });
|
||||||
const mesh = new Mesh(gl, { geometry, program });
|
const mesh = new Mesh(gl, { geometry, program });
|
||||||
|
|
||||||
function resize() {
|
function resize() {
|
||||||
const width = rayContainer.clientWidth;
|
const width = rayContainer.clientWidth;
|
||||||
const height = rayContainer.clientHeight;
|
const height = rayContainer.clientHeight;
|
||||||
renderer.dpr = Math.min(window.devicePixelRatio, 2);
|
renderer.dpr = Math.min(window.devicePixelRatio, 2);
|
||||||
renderer.setSize(width, height);
|
renderer.setSize(width, height);
|
||||||
uniforms.iResolution.value = [width * renderer.dpr, height * renderer.dpr];
|
uniforms.iResolution.value = [width * renderer.dpr, height * renderer.dpr];
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("resize", resize);
|
window.addEventListener("resize", resize);
|
||||||
resize();
|
resize();
|
||||||
|
|
||||||
function animate(time) {
|
function animate(time) {
|
||||||
uniforms.iTime.value = time * 0.001;
|
uniforms.iTime.value = time * 0.001;
|
||||||
renderer.render({ scene: mesh });
|
renderer.render({ scene: mesh });
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
requestAnimationFrame(animate);
|
requestAnimationFrame(animate);
|
||||||
}
|
|
||||||
requestAnimationFrame(animate);
|
|
||||||
|
|
||||||
function initLiquidButtons() {
|
function initLiquidButtons() {
|
||||||
const borderWidth = 0.16;
|
const borderWidth = 0.16;
|
||||||
const brightness = 35;
|
const brightness = 35;
|
||||||
const opacity = 0.55;
|
const opacity = 0.55;
|
||||||
const blur = 4;
|
const blur = 4;
|
||||||
const displace = 1.2;
|
const displace = 1.2;
|
||||||
const borderRadius = 9999;
|
const borderRadius = 9999;
|
||||||
const distortionScale = -380;
|
const distortionScale = -380;
|
||||||
const redOffset = -25;
|
const redOffset = -25;
|
||||||
const greenOffset = 0;
|
const greenOffset = 0;
|
||||||
const blueOffset = 25;
|
const blueOffset = 25;
|
||||||
const xChannel = "R";
|
const xChannel = "R";
|
||||||
const yChannel = "G";
|
const yChannel = "G";
|
||||||
const mixBlendMode = "screen";
|
const mixBlendMode = "screen";
|
||||||
|
|
||||||
document.querySelectorAll(".liquid-glass-btn").forEach((btn, index) => {
|
document.querySelectorAll(".liquid-glass-btn").forEach((btn, index) => {
|
||||||
const filterId = `glass-filter-${index + 1}`;
|
const filterId = `glass-filter-${index + 1}`;
|
||||||
btn.style.setProperty("--filter-id", `url(#${filterId})`);
|
btn.style.setProperty("--filter-id", `url(#${filterId})`);
|
||||||
|
|
||||||
const feImage = btn.querySelector(".fe-image");
|
const feImage = btn.querySelector(".fe-image");
|
||||||
const redChannel = btn.querySelector(".redchannel");
|
const redChannel = btn.querySelector(".redchannel");
|
||||||
const greenChannel = btn.querySelector(".greenchannel");
|
const greenChannel = btn.querySelector(".greenchannel");
|
||||||
const blueChannel = btn.querySelector(".bluechannel");
|
const blueChannel = btn.querySelector(".bluechannel");
|
||||||
const gaussianBlur = btn.querySelector(".gaussianBlur");
|
const gaussianBlur = btn.querySelector(".gaussianBlur");
|
||||||
|
|
||||||
function generateDisplacementMap() {
|
function generateDisplacementMap() {
|
||||||
const rect = btn.getBoundingClientRect();
|
const rect = btn.getBoundingClientRect();
|
||||||
const actualWidth = rect.width || 140;
|
const actualWidth = rect.width || 140;
|
||||||
const actualHeight = rect.height || 48;
|
const actualHeight = rect.height || 48;
|
||||||
|
|
||||||
const svgContent = `
|
const svgContent = `
|
||||||
<svg viewBox="0 0 ${actualWidth} ${actualHeight}" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 ${actualWidth} ${actualHeight}" xmlns="http://www.w3.org/2000/svg">
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="red-grad-${index}" x1="100%" y1="0%" x2="0%" y2="0%">
|
<linearGradient id="red-grad-${index}" x1="100%" y1="0%" x2="0%" y2="0%">
|
||||||
@@ -473,32 +478,33 @@ void main() {
|
|||||||
<rect width="${actualWidth}" height="${actualHeight}" rx="${borderRadius}" fill="url(#blue-grad-${index})" style="mix-blend-mode:${mixBlendMode}"/>
|
<rect width="${actualWidth}" height="${actualHeight}" rx="${borderRadius}" fill="url(#blue-grad-${index})" style="mix-blend-mode:${mixBlendMode}"/>
|
||||||
</svg>
|
</svg>
|
||||||
`;
|
`;
|
||||||
return "data:image/svg+xml," + encodeURIComponent(svgContent);
|
return "data:image/svg+xml," + encodeURIComponent(svgContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
feImage.setAttribute("href", generateDisplacementMap());
|
feImage.setAttribute("href", generateDisplacementMap());
|
||||||
redChannel.setAttribute("scale", distortionScale + redOffset);
|
redChannel.setAttribute("scale", distortionScale + redOffset);
|
||||||
greenChannel.setAttribute("scale", distortionScale + greenOffset);
|
greenChannel.setAttribute("scale", distortionScale + greenOffset);
|
||||||
blueChannel.setAttribute("scale", distortionScale + blueOffset);
|
blueChannel.setAttribute("scale", distortionScale + blueOffset);
|
||||||
[redChannel, greenChannel, blueChannel].forEach((ch) => {
|
[redChannel, greenChannel, blueChannel].forEach((ch) => {
|
||||||
ch.setAttribute("xChannelSelector", xChannel);
|
ch.setAttribute("xChannelSelector", xChannel);
|
||||||
ch.setAttribute("yChannelSelector", yChannel);
|
ch.setAttribute("yChannelSelector", yChannel);
|
||||||
});
|
});
|
||||||
gaussianBlur.setAttribute("stdDeviation", displace);
|
gaussianBlur.setAttribute("stdDeviation", displace);
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
btn.classList.remove("glass-surface--fallback");
|
btn.classList.remove("glass-surface--fallback");
|
||||||
btn.classList.add("glass-surface--svg");
|
btn.classList.add("glass-surface--svg");
|
||||||
|
|
||||||
const observer = new ResizeObserver(() => setTimeout(update, 0));
|
const observer = new ResizeObserver(() => setTimeout(update, 0));
|
||||||
observer.observe(btn);
|
observer.observe(btn);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initLiquidButtons();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
initLiquidButtons();
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -535,8 +541,17 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function initTauriEvents() {
|
async function initTauriEvents() {
|
||||||
const eventApi = window.__TAURI__?.event || window.__TAURI_INTERNALS__;
|
let eventApi = null;
|
||||||
if (!eventApi || typeof eventApi.listen !== 'function') {
|
|
||||||
|
if (window.__TAURI__?.event && typeof window.__TAURI__.event.listen === 'function') {
|
||||||
|
eventApi = window.__TAURI__.event;
|
||||||
|
} else if (window.__TAURI_INTERNALS__ && typeof window.__TAURI_INTERNALS__.listen === 'function') {
|
||||||
|
eventApi = window.__TAURI_INTERNALS__;
|
||||||
|
} else if (window.__TAURI__ && typeof window.__TAURI__.listen === 'function') {
|
||||||
|
eventApi = window.__TAURI__;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eventApi) {
|
||||||
setTimeout(initTauriEvents, 50);
|
setTimeout(initTauriEvents, 50);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -572,7 +587,6 @@ void main() {
|
|||||||
const data = e.payload || e;
|
const data = e.payload || e;
|
||||||
if (data && data.url) {
|
if (data && data.url) {
|
||||||
setStatus("Launching...");
|
setStatus("Launching...");
|
||||||
window.location.href = data.url;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user