diff --git a/public/studio/Studio.js b/public/studio/Studio.js index 5b26105..40a5608 100644 --- a/public/studio/Studio.js +++ b/public/studio/Studio.js @@ -26,6 +26,16 @@ export default class Studio { await this._loadDevices(); this._pushRootColumn(); + // Scope sonrası sanal IP al ve kendime ata. + this.mwse.scope(async () => { + try { + const ip = await this.mwse.virtualPressure.allocAPIPAddress(); + // PeerInfo.set → auth/info → mevcut tüm pairlere yayımlar. + this.mwse.me.info.set('ip', ip); + this._updateMyIP(ip); + } catch (_) {} + }); + // ── Gelen eşleme isteği → bildirim banner'ı ────────────────────── this.mwse.me.on('request/pair', peer => { this._showPairRequest(peer); @@ -34,19 +44,32 @@ export default class Studio { // Eşleşme onaylandı (istek gönderen taraf) this.mwse.me.on('accepted/pair', peer => { this._watchIncoming(peer); + // Yeni paire kendi IP'mizi paylaş. + if (this.mwse.virtualPressure.APIPAddress) { + this.mwse.me.info.set('ip', this.mwse.virtualPressure.APIPAddress); + } this._view.refresh(); - this._setStatus('online', `${peer.socketId.slice(-8)} eşleşmesi kuruldu`); + this._setStatus('online', `${this._peerLabel(peer)} eşleşmesi kuruldu`); }); - // Eşleşme bitti + // Pair info değişince (karşı tarafın IP'si gelince) kolonları yenile. + this.mwse.me.on('accepted/pair', () => this._view.refresh()); + this.mwse.on('room', () => this._view.refresh()); this.mwse.me.on('end/pair', () => this._view.refresh()); - // Oda değişimi - this.mwse.on('room', () => this._view.refresh()); - return this; } + // Toolbar'daki IP/ID kartını güncelle. + _updateMyIP(ip) { + if (this._myIPEl) this._myIPEl.textContent = ip; + } + + // Bir peer için görünen ad: sanal IP varsa onu, yoksa kısa UUID. + _peerLabel(peer) { + return peer.info?.info?.ip || peer.socketId.slice(-8); + } + // ── Araç çubuğu ────────────────────────────────────────────────────────── _buildToolbar() { @@ -59,15 +82,21 @@ export default class Studio { logo.innerHTML = 'MWSE Studio'; bar.appendChild(logo); - // Benim ID kartı + // Benim IP + ID kartı (tıkla → UUID kopyalanır) const idCard = document.createElement('div'); idCard.className = 'mwse-id-card'; - idCard.title = 'Tıkla → Kopyala'; + idCard.title = 'Socket ID\'yi kopyala (paylaşmak için)'; const idLabel = document.createElement('span'); idLabel.className = 'mwse-id-card__label'; idLabel.textContent = 'Kimliğim'; + // Sanal IP (önce boş, allocAPIPAddress sonrası dolar) + this._myIPEl = document.createElement('span'); + this._myIPEl.className = 'mwse-id-card__ip'; + this._myIPEl.textContent = ''; + + // Kısa UUID (ID paylaşımı için) const idValue = document.createElement('span'); idValue.className = 'mwse-id-card__value'; idValue.textContent = '…'; @@ -76,7 +105,7 @@ export default class Studio { idCopy.className = 'mwse-id-card__copy'; idCopy.textContent = '⎘'; - idCard.append(idLabel, idValue, idCopy); + idCard.append(idLabel, this._myIPEl, idValue, idCopy); idCard.addEventListener('click', () => { const id = this.mwse.me.socketId; if (!id || id === '…') return; @@ -90,7 +119,7 @@ export default class Studio { }); }); - this.mwse.me.on('scope', () => { idValue.textContent = this.mwse.me.socketId; }); + this.mwse.me.on('scope', () => { idValue.textContent = this.mwse.me.socketId.slice(-8); }); bar.appendChild(idCard); // Durum @@ -201,7 +230,7 @@ export default class Studio { const pairs = [...this.mwse.pairs.values()]; const items = pairs.map(peer => ({ icon: peer.rtc?.active ? '◉' : '●', - label: peer.socketId, + label: this._peerLabel(peer), meta: () => this._peerMeta(peer), onSelect: () => { this._view.popTo(2); this._pushPeerColumn(peer); } })); @@ -236,9 +265,10 @@ export default class Studio { _peerMeta(peer) { const streams = peer.rtc?._streams?.list() ?? []; - if (streams.length) return `p2p · ${streams.length} akış`; - if (peer.rtc?.active) return `p2p · ${peer.rtc.connectionStatus}`; - return 'websocket'; + const id = peer.socketId.slice(-8); + if (streams.length) return `${id} · p2p · ${streams.length} akış`; + if (peer.rtc?.active) return `${id} · p2p`; + return `${id} · websocket`; } // ── Eş eylem kolonu ─────────────────────────────────────────────────────── @@ -294,7 +324,7 @@ export default class Studio { } }); - this._view.pushColumn(peer.socketId.slice(-12), items, { searchable: false }); + this._view.pushColumn(this._peerLabel(peer), items, { searchable: false }); } // ── Odalar kolonu ───────────────────────────────────────────────────────── @@ -348,7 +378,7 @@ export default class Studio { _pushRoomMembersColumn(room) { const items = [...room.peers.values()].map(peer => ({ icon: peer.selfSocket ? '★' : '●', - label: peer.socketId, + label: peer.selfSocket ? (this.mwse.virtualPressure.APIPAddress || 'Ben') : this._peerLabel(peer), meta: () => this._peerMeta(peer), onSelect: () => { this._view.popTo(3); this._pushPeerColumn(peer); } })); diff --git a/public/studio/style.css b/public/studio/style.css index 25bffca..b5d20fc 100644 --- a/public/studio/style.css +++ b/public/studio/style.css @@ -316,14 +316,24 @@ flex-shrink: 0; } +/* Sanal IP (büyük, belirgin) */ +.mwse-id-card__ip { + font-family: 'Consolas', 'Menlo', monospace; + font-size: 13px; + font-weight: 600; + color: #60cdff; + white-space: nowrap; +} +.mwse-id-card__ip:empty { display: none; } + +/* UUID (küçük, soluk) */ .mwse-id-card__value { font-family: 'Consolas', 'Menlo', monospace; - font-size: 11px; - color: #b0b0b0; + font-size: 10px; + color: #666; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - flex: 1; } .mwse-id-card__copy {