| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- (function () {
- 'use strict';
- const petEl = document.getElementById('pet');
- const ctxMenu = document.getElementById('context-menu');
- const invoke = window.__TAURI__?.core?.invoke;
- let dragStartX = 0, dragStartY = 0;
- let pressTimer = null;
- let isDragging = false;
- // ── 右键菜单 ──────────────────────────────
- petEl.addEventListener('contextmenu', function (e) {
- e.preventDefault();
- const x = Math.min(e.clientX, window.innerWidth - 130);
- const y = Math.min(e.clientY, window.innerHeight - 100);
- ctxMenu.style.left = x + 'px';
- ctxMenu.style.top = y + 'px';
- ctxMenu.style.display = 'block';
- });
- document.addEventListener('click', function (e) {
- if (!ctxMenu.contains(e.target)) ctxMenu.style.display = 'none';
- });
- document.addEventListener('keydown', function (e) {
- if (e.key === 'Escape') ctxMenu.style.display = 'none';
- });
- ctxMenu.addEventListener('click', function (e) {
- const item = e.target.closest('.item');
- if (!item) return;
- const action = item.dataset.action;
- ctxMenu.style.display = 'none';
- if (action === 'settings') invoke?.('open_settings');
- else if (action === 'quit') { try { invoke?.('quit_app'); } catch (_) { window.close(); } }
- });
- // ── 点击 / 长按 / 拖拽 ───────────────────
- petEl.addEventListener('mousedown', function (e) {
- dragStartX = e.clientX;
- dragStartY = e.clientY;
- isDragging = false;
- pressTimer = setTimeout(() => {
- localReact('pet');
- if (backendEnabled()) notifyInteract('pet', {});
- }, 1500);
- });
- petEl.addEventListener('mousemove', function (e) {
- const dx = e.clientX - dragStartX;
- const dy = e.clientY - dragStartY;
- if (Math.abs(dx) > 4 || Math.abs(dy) > 4) {
- isDragging = true;
- clearTimeout(pressTimer);
- notifyDragStart();
- }
- });
- petEl.addEventListener('mouseup', function (e) {
- clearTimeout(pressTimer);
- if (!isDragging) {
- localReact('click');
- // 未登录 / 离线时不打后端,避免只剩「打卡失败」噪音,仅保留本地互动反馈。
- if (backendEnabled()) notifyInteract('click', {});
- } else {
- notifyDragEnd();
- }
- });
- // 本地即时反馈:不依赖后端也能看到宠物对点击的响应。
- function localReact(kind) {
- try { if (window.cfcPetAPI && window.cfcPetAPI.react) window.cfcPetAPI.react(kind); } catch (_) { /* noop */ }
- }
- // 是否已连后端(有令牌)。默认允许,bridge 拉到设置后按 hasToken 修正。
- function backendEnabled() {
- return window.__petHasToken !== false;
- }
- function notifyInteract(action, data) {
- try {
- window.cfcHost.onInteract(action, JSON.stringify(data));
- } catch (err) { console.log('[interaction]', action, data); }
- }
- function notifyDragStart() {
- try { window.cfcHost.onDragStart(); } catch (e) { /* noop */ }
- }
- function notifyDragEnd() {
- try { window.cfcHost.onDragEnd(); } catch (e) { /* noop */ }
- }
- })();
|