Live video on the AT Protocol

Compare changes

Choose any two refs to compare.

+34 -21
+1
js/app/components/login/login.tsx
··· 27 28 // check for stored return route on mount 29 useEffect(() => { 30 storage.getItem("returnRoute").then((stored) => { 31 if (stored) { 32 try {
··· 27 28 // check for stored return route on mount 29 useEffect(() => { 30 + if (Platform.OS !== "web") return; 31 storage.getItem("returnRoute").then((stored) => { 32 if (stored) { 33 try {
+6 -1
js/app/features/bluesky/blueskyProvider.tsx
··· 2 import { storage } from "@streamplace/components"; 3 import { useURL } from "expo-linking"; 4 import { useEffect, useState } from "react"; 5 import { useStore } from "store"; 6 import { useIsReady, useOAuthSession, useUserProfile } from "store/hooks"; 7 import { navigateToRoute } from "utils/navigation"; ··· 23 loadOAuthClient(); 24 25 // load return route from storage on mount 26 storage.getItem("returnRoute").then((stored) => { 27 if (stored) { 28 try { ··· 82 if ( 83 lastAuthStatus !== "loggedIn" && 84 authStatus === "loggedIn" && 85 - returnRoute 86 ) { 87 console.log( 88 "Login successful, navigating back to returnRoute:",
··· 2 import { storage } from "@streamplace/components"; 3 import { useURL } from "expo-linking"; 4 import { useEffect, useState } from "react"; 5 + import { Platform } from "react-native"; 6 import { useStore } from "store"; 7 import { useIsReady, useOAuthSession, useUserProfile } from "store/hooks"; 8 import { navigateToRoute } from "utils/navigation"; ··· 24 loadOAuthClient(); 25 26 // load return route from storage on mount 27 + if (Platform.OS !== "web") { 28 + return; 29 + } 30 storage.getItem("returnRoute").then((stored) => { 31 if (stored) { 32 try { ··· 86 if ( 87 lastAuthStatus !== "loggedIn" && 88 authStatus === "loggedIn" && 89 + returnRoute && 90 + Platform.OS === "web" 91 ) { 92 console.log( 93 "Login successful, navigating back to returnRoute:",
+8 -3
js/app/hooks/useBlueskyNotifications.tsx
··· 1 import { useToast } from "@streamplace/components"; 2 import { CircleX } from "lucide-react-native"; 3 import { useEffect } from "react"; 4 import { useStore } from "../store"; 5 6 function titleCase(str: string) { ··· 18 let toast = useToast(); 19 const notification = useStore((state) => state.notification); 20 const clearNotification = useStore((state) => state.clearNotification); 21 22 useEffect(() => { 23 if (notification) { ··· 41 { 42 duration: 100, 43 variant: notification.type, 44 - actionLabel: "Copy message", 45 iconLeft: CircleX, 46 onAction: () => { 47 navigator.clipboard.writeText( ··· 59 notification.message, 60 { 61 variant: notification.type, 62 - actionLabel: "Copy message", 63 onAction: () => { 64 navigator.clipboard.writeText(notification.message); 65 }, ··· 74 notification.message, 75 { 76 variant: notification.type, 77 - actionLabel: "Copy message", 78 onAction: () => { 79 navigator.clipboard.writeText(notification.message); 80 },
··· 1 import { useToast } from "@streamplace/components"; 2 import { CircleX } from "lucide-react-native"; 3 import { useEffect } from "react"; 4 + import { Platform } from "react-native"; 5 + import clearQueryParams from "utils/clear-query-params"; 6 import { useStore } from "../store"; 7 8 function titleCase(str: string) { ··· 20 let toast = useToast(); 21 const notification = useStore((state) => state.notification); 22 const clearNotification = useStore((state) => state.clearNotification); 23 + 24 + // we've already saved the notif to the store 25 + clearQueryParams(["error", "error_description"]); 26 27 useEffect(() => { 28 if (notification) { ··· 46 { 47 duration: 100, 48 variant: notification.type, 49 + actionLabel: Platform.OS === "web" ? "Copy message" : undefined, 50 iconLeft: CircleX, 51 onAction: () => { 52 navigator.clipboard.writeText( ··· 64 notification.message, 65 { 66 variant: notification.type, 67 + actionLabel: Platform.OS === "web" ? "Copy message" : undefined, 68 onAction: () => { 69 navigator.clipboard.writeText(notification.message); 70 }, ··· 79 notification.message, 80 { 81 variant: notification.type, 82 + actionLabel: Platform.OS === "web" ? "Copy message" : undefined, 83 onAction: () => { 84 navigator.clipboard.writeText(notification.message); 85 },
+2 -16
js/app/store/slices/blueskySlice.ts
··· 19 PlaceStreamServerSettings, 20 StreamplaceAgent, 21 } from "streamplace"; 22 import { privateKeyToAccount } from "viem/accounts"; 23 import { StateCreator } from "zustand"; 24 import createOAuthClient, { ··· 117 createServerSettingsRecord: (debugRecording: boolean) => Promise<void>; 118 } 119 120 - const clearQueryParams = () => { 121 - if (Platform.OS !== "web") { 122 - return; 123 - } 124 - const u = new URL(document.location.href); 125 - const params = new URLSearchParams(u.search); 126 - if (u.search === "") { 127 - return; 128 - } 129 - params.delete("iss"); 130 - params.delete("state"); 131 - params.delete("code"); 132 - u.search = params.toString(); 133 - window.history.replaceState(null, "", u.toString()); 134 - }; 135 - 136 const uploadThumbnail = async ( 137 handle: string, 138 u: URL, ··· 217 notification: null, 218 219 clearNotification: () => { 220 set({ notification: null }); 221 }, 222
··· 19 PlaceStreamServerSettings, 20 StreamplaceAgent, 21 } from "streamplace"; 22 + import clearQueryParams from "utils/clear-query-params"; 23 import { privateKeyToAccount } from "viem/accounts"; 24 import { StateCreator } from "zustand"; 25 import createOAuthClient, { ··· 118 createServerSettingsRecord: (debugRecording: boolean) => Promise<void>; 119 } 120 121 const uploadThumbnail = async ( 122 handle: string, 123 u: URL, ··· 202 notification: null, 203 204 clearNotification: () => { 205 + clearQueryParams(); 206 set({ notification: null }); 207 }, 208
+15
js/app/utils/clear-query-params.ts
···
··· 1 + import { Platform } from "react-native"; 2 + 3 + export default function clearQueryParams(par = ["iss", "state", "code"]) { 4 + if (Platform.OS !== "web") { 5 + return; 6 + } 7 + const u = new URL(document.location.href); 8 + const params = new URLSearchParams(u.search); 9 + if (u.search === "") { 10 + return; 11 + } 12 + par.forEach((p) => params.delete(p)); 13 + u.search = params.toString(); 14 + window.history.replaceState(null, "", u.toString()); 15 + }
+2 -1
js/docs/package.json
··· 23 }, 24 "devDependencies": { 25 "starlight-sidebar-topics": "^0.6.2" 26 - } 27 }
··· 23 }, 24 "devDependencies": { 25 "starlight-sidebar-topics": "^0.6.2" 26 + }, 27 + "private": true 28 }