Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion infra/cloud-run-relay/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"start": "node server.mjs"
},
"dependencies": {
"firebase-admin": "^13.0.0",
"ws": "^8.18.1"
}
}
49 changes: 0 additions & 49 deletions infra/cloud-run-relay/server.mjs
Original file line number Diff line number Diff line change
@@ -1,44 +1,7 @@
import { initializeApp } from "firebase-admin/app";
import { Timestamp, getFirestore } from "firebase-admin/firestore";
import http from "node:http";
import { WebSocketServer } from "ws";

const port = Number(process.env.PORT || 8080);
const RELAY_ROOMS_COLLECTION = "relay_rooms";
const HEARTBEAT_INTERVAL_MS = 60_000;

// Auto-initializes from the Cloud Run service account.
initializeApp();
const firestore = getFirestore();

async function setRoomPresence(room) {
try {
await firestore.collection(RELAY_ROOMS_COLLECTION).doc(room).set({
connectedAt: Timestamp.now(),
lastHeartbeat: Timestamp.now(),
});
} catch (err) {
console.error(`[presence] set failed for ${room}:`, err.message);
}
}

async function updateRoomHeartbeat(room) {
try {
await firestore.collection(RELAY_ROOMS_COLLECTION).doc(room).update({
lastHeartbeat: Timestamp.now(),
});
} catch (err) {
console.error(`[presence] heartbeat failed for ${room}:`, err.message);
}
}

async function deleteRoomPresence(room) {
try {
await firestore.collection(RELAY_ROOMS_COLLECTION).doc(room).delete();
} catch (err) {
console.error(`[presence] delete failed for ${room}:`, err.message);
}
}

const server = http.createServer((req, res) => {
if (req.url === "/healthz") {
Expand All @@ -57,12 +20,6 @@ function roomKey(room) {
return `room:${room}`;
}

// Refresh lastHeartbeat for every live room so the backend can filter stale entries.
setInterval(() => {
for (const key of rooms.keys()) {
updateRoomHeartbeat(key.slice("room:".length));
}
}, HEARTBEAT_INTERVAL_MS);

const wss = new WebSocketServer({ server, path: "/relay" });

Expand All @@ -81,11 +38,6 @@ wss.on("connection", (ws, req) => {
peers.add(ws);
rooms.set(key, peers);

// Write presence the first time any peer joins this room.
if (peers.size === 1) {
setRoomPresence(room);
}

if (existingPeers.length > 0) {
const msg = JSON.stringify({ type: "peer_joined" });
for (const peer of existingPeers) {
Expand All @@ -107,7 +59,6 @@ wss.on("connection", (ws, req) => {
peers.delete(ws);
if (peers.size === 0) {
rooms.delete(key);
deleteRoomPresence(room);
}
});
});
Expand Down
8 changes: 0 additions & 8 deletions ios/GoVibeFeaturePackage/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,12 @@ let package = Package(
),
],
dependencies: [
.package(url: "https://github.com/firebase/firebase-ios-sdk.git", from: "11.10.0"),
.package(path: "../ThirdParty/SwiftTerm")
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: "GoVibeFeature",
dependencies: [
.product(name: "FirebaseCore", package: "firebase-ios-sdk"),
.product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
.product(name: "FirebaseFirestore", package: "firebase-ios-sdk"),
.product(name: "FirebaseMessaging", package: "firebase-ios-sdk"),
.product(name: "FirebaseFunctions", package: "firebase-ios-sdk"),
.product(name: "SwiftTerm", package: "SwiftTerm")
]
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,9 @@ import Foundation

enum AppRuntimeConfig {
private enum Keys {
static let gcpRegion = "GOVIBE_GCP_REGION"
static let gcpProjectID = "GOVIBE_GCP_PROJECT_ID"
static let gcpRelayHost = "GOVIBE_GCP_RELAY_HOST"
}

static let apiBaseURL: URL = {
let region = requiredConfiguredValue(for: Keys.gcpRegion, expectedExample: "us-west1")
let projectID = requiredConfiguredValue(for: Keys.gcpProjectID, expectedExample: "my-project-id")
let raw = "https://\(region)-\(projectID).cloudfunctions.net/api"
guard let url = URL(string: raw) else {
fatalError("Invalid assembled API URL: \(raw)")
}
return url
}()

static let relayWebSocketBase: String = {
let relayHostRaw = requiredConfiguredValue(
for: Keys.gcpRelayHost,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import FirebaseCore
import Foundation

public enum GoVibeBootstrap {
public static func configureFirebaseIfNeeded() {
if FirebaseApp.app() == nil {
FirebaseApp.configure()
}
// Firebase removed.
}
}
25 changes: 0 additions & 25 deletions ios/GoVibeFeaturePackage/Sources/GoVibeFeature/Models.swift
Original file line number Diff line number Diff line change
@@ -1,30 +1,5 @@
import Foundation

struct SessionCreateResponse: Codable {
struct Ice: Codable {
struct Turn: Codable {
let username: String
let credential: String
let ttl: Int
let urls: [String]
}

let policy: String
let relayRequired: Bool
let turn: Turn
}

let sessionId: String
let signalingPath: String
let token: String
let ice: Ice
}

struct SessionDiscoveryResponse: Codable {
let roomIds: [String]
let count: Int
}

struct TerminalLine: Identifiable {
let id = UUID()
let text: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ struct SessionDetailView: View {
.background(Color.black)
.accessibilityIdentifier("govibe_root_view")
.task {
await viewModel.bootstrapAuth()
viewModel.connectRelayNow()
}
.onDisappear {
viewModel.disconnectRelay()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ struct SessionListView: View {
}
.alert("New Session", isPresented: $showingAddAlert) {
TextField("Room ID", text: $newRoomId)
.autocorrectionDisabled()
.modifier(NeverAutocapitalize())
Button("Add") {
store.add(roomId: newRoomId)
newRoomId = ""
Expand Down Expand Up @@ -176,6 +178,16 @@ struct SessionListView: View {
}
}

private struct NeverAutocapitalize: ViewModifier {
func body(content: Content) -> some View {
#if canImport(UIKit)
content.textInputAutocapitalization(.never)
#else
content
#endif
}
}

private struct SessionPlaceholderView: View {
var body: some View {
ContentUnavailableView(
Expand Down
Loading