Studio: UUID yerine sanal IP gösterimi

Akış:
  - scope sonrası allocAPIPAddress() → 10.x.x.x al
  - PeerInfo.set('ip', ip) → auth/info → tüm mevcut pairlere yayımlar
  - accepted/pair sonrası tekrar set() → yeni paire de ulaşır
  - pair/info sinyali → peer.info.info.ip güncellenir (SDK zaten yapıyor)

Araç çubuğu ID kartı:
  - Sanal IP: büyük, mavi (10.x.x.x) — IP alındıkça güncellenir
  - Kısa UUID: küçük, soluk (son 8 karakter) — scope'ta dolar
  - Tıkla → tam UUID kopyalanır (paylaşmak için hâlâ gerekli)

Eşler kolonunda:
  - Etiket: peer.info.info.ip (varsa) yoksa kısa UUID
  - Meta: kısa UUID · bağlantı türü · akış sayısı

Eş eylem kolonu başlığı: IP veya kısa UUID
Oda üyeleri: kendi kaydı için sanal IP gösterilir

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
abdussamedulutas 2026-06-17 13:46:27 +03:00
parent d9598ba15f
commit 0c654ae4c8
2 changed files with 58 additions and 18 deletions

View File

@ -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 <span style="color:#0078d4">Studio</span>';
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); }
}));

View File

@ -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 {