Uzun sure acik kalan IDE'de "Telefon ekle" ilk istegi olu bir keep-alive baglantisinda kaybedebiliyordu; bulusma kaydi yayinlanamayinca kod yolu bes dakika boyunca "Kodla baglanma su an kullanilamiyor" kaliyordu (QR calisiyordu). - publishPairOffer: en cok 4 deneme (0,5 / 1,5 / 3 sn); ag hatasi, 5xx ve 429 yeniden denenir, 422 kalicidir; yaniti kaybolan denemeden sonraki 409 kaydin yerinde oldugu anlamina gelir (iptal jetonu yoktur, kayit kendiliginden biter). - Pencerede "Yeniden dene": ayni kod ve QR ile kaydi yeniden yayinlar. - Role oturumu kaydi ve "Giris yap" baslangici icin tek ek deneme (zaman asimi yeniden denenmez). - Gunluge yalniz "pair offer published / failed after N tries" duser; kod, lookup ve jeton yazilmaz. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B8ppceaR5s6cvMnm7uGRnf
53 lines
2.7 KiB
JavaScript
53 lines
2.7 KiB
JavaScript
// "Telefon bağlantısı" window: a thin IPC shell around the controller built in
|
||
// electron/mobile-lan-proxy.ts (createMobileLink). The controller lives in the
|
||
// main process for the whole app run — closing this window only cancels a
|
||
// pairing in progress; paired phones stay connected.
|
||
import { join } from 'node:path'
|
||
import { BrowserWindow, ipcMain } from 'electron'
|
||
|
||
const CODED = /^aiturk-mobile:[a-z_]+$/
|
||
|
||
export function createMobileWindow({ assets, link, show = true }) {
|
||
const window = new BrowserWindow({ width: 560, height: 800, show, title: 'AITURK · Telefon bağlantısı',
|
||
webPreferences: { preload: join(assets, 'mobile-preload.cjs'), contextIsolation: true,
|
||
nodeIntegration: false, sandbox: true } })
|
||
window.setMenu(null)
|
||
window.webContents.setWindowOpenHandler(() => ({ action: 'deny' }))
|
||
window.webContents.on('will-navigate', event => event.preventDefault())
|
||
const actions = {
|
||
state: () => link.state(),
|
||
enable: () => link.enable(),
|
||
disable: () => link.disable(),
|
||
'pair.begin': () => link.pairBegin(),
|
||
'pair.cancel': () => link.pairCancel(),
|
||
// Publishes the running pairing's rendezvous record again; the code and the QR stay as they are.
|
||
'pair.republish': () => link.pairRepublish(),
|
||
devices: () => link.devices(),
|
||
'device.revoke': params => link.deviceRevoke(params?.deviceId),
|
||
// The only actions that may raise a UAC prompt; both are explicit button presses.
|
||
'lan.allow': () => link.lanAllow(),
|
||
'lan.disallow': () => link.lanDisallow(),
|
||
'firewall.allow': () => link.lanAllow(),
|
||
'firewall.retry': () => link.lanAllow(),
|
||
'relay.renew': () => link.relayRenew(),
|
||
'firewall.remove': () => link.firewallRemove(),
|
||
}
|
||
const handler = async (event, action, params) => {
|
||
if (event.sender !== window.webContents || event.senderFrame !== window.webContents.mainFrame) throw new Error('aiturk-mobile:forbidden')
|
||
if (typeof action !== 'string' || !Object.hasOwn(actions, action)) throw new Error('aiturk-mobile:unsupported')
|
||
try { return await actions[action](params) } catch (error) {
|
||
// Only fixed codes cross to the renderer; never upstream error text.
|
||
throw new Error(CODED.test(error?.message) ? error.message : 'aiturk-mobile:failed')
|
||
}
|
||
}
|
||
const unsubscribe = link.onEvent(event => { if (!window.isDestroyed()) window.webContents.send('aiturk-mobile-event', event) })
|
||
ipcMain.handle('aiturk-mobile', handler)
|
||
window.on('closed', () => {
|
||
unsubscribe(); ipcMain.removeHandler('aiturk-mobile')
|
||
// The code on screen is gone with the window; do not leave pairing open behind it.
|
||
void link.pairCancel().catch(() => {})
|
||
})
|
||
void window.loadFile(join(assets, 'mobile-host.html'))
|
||
return window
|
||
}
|