···11-import { Link, useNavigation } from "@react-navigation/native";
22-import { NavigationProp, ParamListBase } from "@react-navigation/native";
11+import {
22+ Link,
33+ NavigationProp,
44+ ParamListBase,
55+ useNavigation,
66+} from "@react-navigation/native";
37import usePlatform from "hooks/usePlatform";
88+import { useEffect } from "react";
49import { Pressable, StyleProp, ViewStyle } from "react-native";
510import Loading from "./loading/loading";
66-import { useEffect } from "react";
711812export type LinkParams = { screen: string; params?: Record<string, string> };
913
+18-18
js/app/components/chat/chat-box.tsx
···11import { useNavigation } from "@react-navigation/native";
22+import {
33+ Palette,
44+ SquareArrowOutUpRight,
55+ X as XIcon,
66+} from "@tamagui/lucide-icons";
27import { useToastController } from "@tamagui/toast";
88+import { emojiEmitter } from "components/emoji-picker/emoji-emitter";
99+import { EmojiPicker } from "components/emoji-picker/emoji-picker";
1010+import NameColorPicker from "components/name-color-picker/name-color-picker";
311import {
412 chatMessage,
1313+ selectChatProfile,
514 selectIsReady,
615 selectUserProfile,
77- selectChatProfile,
816} from "features/bluesky/blueskySlice";
917import {
1818+ addLocalChatMessage,
1019 LivestreamViewHydrated,
1111- usePlayerLivestream,
1212- addLocalChatMessage,
2020+ MessageViewHydrated,
2121+ useChat,
2222+ usePlayerActions,
1323 usePlayerId,
2424+ usePlayerLivestream,
1425 useReplyToMessage,
1515- usePlayerActions,
1616- useChat,
1717- MessageViewHydrated,
1826} from "features/player/playerSlice";
1927import {
2028 chatWarn,
2129 selectChatWarned,
2230} from "features/streamplace/streamplaceSlice";
2323-import { useRef, useState, useEffect } from "react";
3131+import { usePreloadEmoji } from "hooks/usePreloadEmoji";
3232+import { useEffect, useRef, useState } from "react";
2433import { Keyboard } from "react-native";
2534import { useAppDispatch, useAppSelector } from "store/hooks";
2626-import { Button, Form, Input, isWeb, TextArea, View, Text } from "tamagui";
2727-import {
2828- Palette,
2929- SquareArrowOutUpRight,
3030- X as XIcon,
3131-} from "@tamagui/lucide-icons";
3232-import NameColorPicker from "components/name-color-picker/name-color-picker";
3535+import { Button, Form, Input, isWeb, Text, TextArea, View } from "tamagui";
3636+import EmojiSuggestions, { EmojiSuggestion } from "./emoji-suggestions";
3337import MentionSuggestions, { MentionSuggestion } from "./mention-suggestions";
3434-import { emojiEmitter } from "components/emoji-picker/emoji-emitter";
3535-import { EmojiPicker } from "components/emoji-picker/emoji-picker";
3636-import EmojiSuggestions, { EmojiSuggestion } from "./emoji-suggestions";
3737-import { usePreloadEmoji } from "hooks/usePreloadEmoji";
38383939const getParticipantSuggestions = (
4040 chat: MessageViewHydrated[],
+6-6
js/app/components/chat/chat.tsx
···11-import { Settings, X, Reply } from "@tamagui/lucide-icons";
11+import { Reply, Settings, X } from "@tamagui/lucide-icons";
22import {
33 createBlockRecord,
44 selectUserProfile,
···66import {
77 MessageViewHydrated,
88 useChat,
99- usePlayerLivestream,
109 usePlayerActions,
1010+ usePlayerLivestream,
1111} from "features/player/playerSlice";
1212+import usePlatform from "hooks/usePlatform";
1213import { useEffect, useRef, useState } from "react";
1313-import { TouchableOpacity, Linking } from "react-native";
1414+import { Linking, TouchableOpacity } from "react-native";
1415import { useAppDispatch, useAppSelector } from "store/hooks";
1515-import usePlatform from "hooks/usePlatform";
16161717-import { Button, ScrollView, Sheet, Text, useMedia, View } from "tamagui";
1817import { RichText } from "@atproto/api";
1918import {
2019 isMention,
2120 Link,
2221 Mention,
2322} from "@atproto/api/dist/client/types/app/bsky/richtext/facet";
2323+import { $Typed } from "@atproto/api/src/client/util";
2424+import { Button, ScrollView, Sheet, Text, useMedia, View } from "tamagui";
2425import { RichtextSegment, segmentize } from "../../utils/facet";
2525-import { $Typed } from "@atproto/api/src/client/util";
26262727export default function Chat({
2828 isChatVisible,
+1-1
js/app/components/chat/emoji-suggestions.tsx
···11-import { ScrollView, Text, View } from "tamagui";
21import { TouchableOpacity } from "react-native";
22+import { ScrollView, Text, View } from "tamagui";
3344export interface EmojiSuggestion {
55 emoji: string;
+1-1
js/app/components/chat/mention-suggestions.tsx
···11-import { ScrollView, Text, View } from "tamagui";
21import { TouchableOpacity } from "react-native";
22+import { ScrollView, Text, View } from "tamagui";
3344export interface MentionSuggestion {
55 did: string;
+1-1
js/app/components/countdown.tsx
···11+import * as chrono from "chrono-node";
12import { useEffect, useState } from "react";
23import {
34 Text,
···78 useMedia,
89 useWindowDimensions,
910} from "tamagui";
1010-import * as chrono from "chrono-node";
11111212const CountdownBox = styled(View, {
1313 alignSelf: "center",
+6-6
js/app/components/create-livestream.tsx
···11-import { useEffect, useState } from "react";
22-import { Button, Label, Paragraph, TextArea, View, isWeb } from "tamagui";
31import { useToastController } from "@tamagui/toast";
22+import ThumbnailSelector from "components/thumbnail-selector";
43import {
54 createLivestreamRecord,
65 selectNewLivestream,
76 selectUserProfile,
87} from "features/bluesky/blueskySlice";
99-import { useAppDispatch, useAppSelector } from "store/hooks";
1010-import { useLiveUser } from "hooks/useLiveUser";
1111-import ThumbnailSelector from "components/thumbnail-selector";
128import { useCaptureVideoFrame } from "hooks/useCaptureVideoFrame";
1313-import { useWindowDimensions, ScrollView } from "react-native";
99+import { useLiveUser } from "hooks/useLiveUser";
1010+import { useEffect, useState } from "react";
1111+import { ScrollView, useWindowDimensions } from "react-native";
1212+import { useAppDispatch, useAppSelector } from "store/hooks";
1313+import { Button, Label, Paragraph, TextArea, View, isWeb } from "tamagui";
14141515export default function CreateLivestream() {
1616 const dispatch = useAppDispatch();
+1-2
js/app/components/debug/breakpoint-indicator.tsx
···11-import { Text, View } from "tamagui";
22-import { useMedia } from "tamagui";
11+import { Text, useMedia, View } from "tamagui";
3243export default function BreakpointIndicator() {
54 const media = useMedia();
+3-3
js/app/components/edit-livestream.tsx
···11-import { useEffect, useState } from "react";
22-import { Button, H3, Label, Paragraph, Text, TextArea, View } from "tamagui";
31import { useToastController } from "@tamagui/toast";
42import {
53 selectNewLivestream,
64 selectUserProfile,
75 updateLivestreamRecord,
86} from "features/bluesky/blueskySlice";
99-import { useAppDispatch, useAppSelector } from "store/hooks";
107import { useLiveUser } from "hooks/useLiveUser";
88+import { useEffect, useState } from "react";
119import { ScrollView } from "react-native";
1010+import { useAppDispatch, useAppSelector } from "store/hooks";
1111+import { Button, H3, Label, Paragraph, Text, TextArea, View } from "tamagui";
12121313export default function UpdateLivestream({
1414 playerId,
+1-2
js/app/components/emoji-picker/emoji-picker.tsx
···11import Picker from "@emoji-mart/react";
22+import { isWeb, View } from "tamagui";
23import { emojiEmitter } from "./emoji-emitter";
33-import { View } from "tamagui";
44-import { isWeb } from "tamagui";
5465export type Emoji = {
76 native: string;
+1-1
js/app/components/error/error.tsx
···11-import { View, Text, Button } from "tamagui";
11+import { Button, Text, View } from "tamagui";
2233export default function (props: { onRetry: () => void }) {
44 return (
+4-4
js/app/components/follow-button.tsx
···11+import { Check, Plus } from "@tamagui/lucide-icons";
12import React, { useEffect, useState } from "react";
22-import { useAppDispatch, useAppSelector } from "../store/hooks";
33-import { selectStreamplace } from "../features/streamplace/streamplaceSlice";
33+import { Button, Text, View } from "tamagui";
44import { followUser, unfollowUser } from "../features/bluesky/blueskySlice";
55-import { Button, View, Text } from "tamagui";
66-import { Plus, Check } from "@tamagui/lucide-icons";
55+import { selectStreamplace } from "../features/streamplace/streamplaceSlice";
66+import { useAppDispatch, useAppSelector } from "../store/hooks";
7788/**
99 * FollowButton component for following/unfollowing a streamer.
+1-1
js/app/components/get-apps.tsx
···11-import { XStack, Image, Anchor } from "tamagui";
11+import { Anchor, Image, XStack } from "tamagui";
2233const RATIO = 3.39741547176;
44const WIDTH = 200;
+2-2
js/app/components/home/cards.tsx
···11-import { Image } from "react-native";
22-import { Stack, Text, XStack, YStack, isWeb, useMedia, View } from "tamagui";
31import Viewers from "components/viewers";
42import useStreamplaceNode from "hooks/useStreamplaceNode";
33+import { Image } from "react-native";
44+import { isWeb, Stack, Text, useMedia, View, XStack, YStack } from "tamagui";
5566export type StreamCardSize = "xs" | "sm" | "md" | "lg" | "xl";
77
+3-3
js/app/components/home/live-dot.tsx
···11-import React, { useEffect } from "react";
11+import { useEffect } from "react";
22import { StyleSheet, View } from "react-native";
33import Animated, {
44- useSharedValue,
54 useAnimatedStyle,
55+ useSharedValue,
66+ withRepeat,
67 withTiming,
77- withRepeat,
88} from "react-native-reanimated";
991010export default function LiveDot() {
+1-1
js/app/components/index.tsx
···11export { Countdown } from "./countdown";
22export { Player } from "./player/player";
33-export { Settings } from "./settings/settings";
43export { default as Provider } from "./provider/provider";
44+export { Settings } from "./settings/settings";
+3-3
js/app/components/live-dashboard/stream-key.tsx
···11import { useToastController } from "@tamagui/toast";
22+import { Redirect } from "components/aqlink";
23import Loading from "components/loading/loading";
34import {
45 clearStreamKeyRecord,
56 createStreamKeyRecord,
66- selectUserProfile,
77 selectIsReady,
88+ selectUserProfile,
89} from "features/bluesky/blueskySlice";
910import { useEffect, useState } from "react";
1011import { useAppDispatch, useAppSelector } from "store/hooks";
1111-import { View, Paragraph, Button, Text } from "tamagui";
1212-import { Redirect } from "components/aqlink";
1212+import { Button, Paragraph, Text, View } from "tamagui";
1313const Row = ({ children }: { children: React.ReactNode }) => {
1414 return (
1515 <View w="100%" f={1} fd="row" padding="$4">
+1-1
js/app/components/live-dashboard/waiting.tsx
···11import Loading from "components/loading/loading";
22-import { View, Text } from "tamagui";
22+import { Text, View } from "tamagui";
3344export default function Waiting() {
55 return (
+8-8
js/app/components/livestream/livestream.tsx
···11+import { MessageCircleMore, MessageCircleOff } from "@tamagui/lucide-icons";
22+import { useToastController } from "@tamagui/toast";
13import Chat from "components/chat/chat";
24import ChatBox from "components/chat/chat-box";
55+import FollowButton from "components/follow-button";
36import Loading from "components/loading/loading";
47import { Player } from "components/player/player";
58import { PlayerProps } from "components/player/props";
69import PlayerProvider from "components/player/provider";
710import Popup from "components/popup";
88-import Viewers from "components/viewers";
911import Timer from "components/timer";
1212+import Viewers from "components/viewers";
1313+import { useFullscreen } from "contexts/FullscreenContext";
1414+import { getProfile, selectProfiles } from "features/bluesky/blueskySlice";
1015import { usePlayer } from "features/player/playerSlice";
1116import {
1217 selectTelemetry,
···1722import { useCallback, useEffect, useState } from "react";
1823import {
1924 LayoutChangeEvent,
2525+ Linking,
2026 View as RNView,
2127 SafeAreaView,
2222- Linking,
2328} from "react-native";
2929+import storage from "storage";
2430import { useAppDispatch, useAppSelector } from "store/hooks";
2531import {
2632 Button,
···3137 useWindowDimensions,
3238 View,
3339} from "tamagui";
3434-import { MessageCircleOff, MessageCircleMore } from "@tamagui/lucide-icons";
3535-import FollowButton from "components/follow-button";
3636-import { useToastController } from "@tamagui/toast";
3737-import { selectProfiles, getProfile } from "features/bluesky/blueskySlice";
3838-import storage from "storage";
3939-import { useFullscreen } from "contexts/FullscreenContext";
40404141export default function Livestream(props: Partial<PlayerProps>) {
4242 return (
+1-1
js/app/components/loading/loading.tsx
···11-import { View, Spinner as TamaguiSpinner } from "tamagui";
11+import { Spinner as TamaguiSpinner, View } from "tamagui";
2233export default function () {
44 return (
+4-5
js/app/components/login/login.tsx
···11-import { AtpBaseClient } from "streamplace";
11+import { useNavigation } from "@react-navigation/native";
22+import { CircleHelp } from "@tamagui/lucide-icons";
33+import { useToastController } from "@tamagui/toast";
44+import Loading from "components/loading/loading";
25import NameColorPicker from "components/name-color-picker/name-color-picker";
36import {
47 login,
···2124 XStack,
2225 YStack,
2326} from "tamagui";
2424-import Loading from "components/loading/loading";
2525-import { useToastController } from "@tamagui/toast";
2626-import { useNavigation } from "@react-navigation/native";
2727-import { CircleHelp } from "@tamagui/lucide-icons";
28272928export default function Login() {
3029 const dispatch = useAppDispatch();
+4-4
js/app/components/login/signup.tsx
···11+import { useNavigation } from "@react-navigation/native";
22+import { CircleHelp } from "@tamagui/lucide-icons";
33+import { useToastController } from "@tamagui/toast";
44+import Loading from "components/loading/loading";
15import {
26 login,
37 selectIsReady,
···1721 XStack,
1822 YStack,
1923} from "tamagui";
2020-import Loading from "components/loading/loading";
2121-import { useToastController } from "@tamagui/toast";
2222-import { useNavigation } from "@react-navigation/native";
2323-import { CircleHelp } from "@tamagui/lucide-icons";
24242525export default function SignUp() {
2626 const dispatch = useAppDispatch();
···11import { X } from "@tamagui/lucide-icons";
22-import { View, Button, ViewProps } from "tamagui";
22+import { Button, View, ViewProps } from "tamagui";
3344export default function Popup({
55 onClose,
+3-3
js/app/components/provider/provider.shared.tsx
···55} from "@react-navigation/native";
66import { ToastProvider, ToastViewport } from "@tamagui/toast";
77import { useFonts } from "expo-font";
88+import BlueskyProvider from "features/bluesky/blueskyProvider";
89import StreamplaceProvider from "features/streamplace/streamplaceProvider";
910import React from "react";
1111+import { Provider as ReduxProvider } from "react-redux";
1212+import { store } from "store/store";
1013import { PortalProvider, TamaguiProvider } from "tamagui";
1114import config from "tamagui.config";
1215import { CurrentToast } from "./CurrentToast";
1313-import { Provider as ReduxProvider } from "react-redux";
1414-import BlueskyProvider from "features/bluesky/blueskyProvider";
1515-import { store } from "store/store";
1616export default function Provider({
1717 children,
1818 linking,
+2-2
js/app/components/provider/provider.tsx
···22import "@rainbow-me/rainbowkit/styles.css";
3344import { LinkingOptions } from "@react-navigation/native";
55-import SharedProvider from "./provider.shared";
66-import React, { useEffect } from "react";
75import { WalletProvider } from "hooks/useWallet";
66+import React, { useEffect } from "react";
77+import SharedProvider from "./provider.shared";
8899export default function Provider({
1010 children,
+4-4
js/app/components/settings/settings.tsx
···11import {
22+ DEFAULT_URL,
23 selectTelemetry,
34 setURL,
45 telemetryOpt,
55- DEFAULT_URL,
66} from "features/streamplace/streamplaceSlice";
77import useStreamplaceNode from "hooks/useStreamplaceNode";
88-import { useState, useEffect } from "react";
88+import { useEffect, useState } from "react";
99+import { Switch } from "react-native";
910import { useAppDispatch, useAppSelector } from "store/hooks";
1010-import { Button, Form, H3, Input, View, XStack, Text, isWeb } from "tamagui";
1111+import { Button, Form, H3, Input, Text, View, XStack, isWeb } from "tamagui";
1112import { Updates } from "./updates";
1212-import { Switch } from "react-native";
13131414export function Settings() {
1515 const dispatch = useAppDispatch();
+2-2
js/app/components/settings/updates.native.tsx
···11+import { ToastViewport, useToastController } from "@tamagui/toast";
12import * as ExpoUpdates from "expo-updates";
23import { useEffect, useState } from "react";
44+import { Platform } from "react-native";
35import { Button, H2, H5, Text, View } from "tamagui";
44-import { ToastViewport, useToastController } from "@tamagui/toast";
56import pkg from "../../package.json";
66-import { Platform } from "react-native";
7788export function Updates() {
99 const version = pkg.version;
+1-1
js/app/components/settings/updates.tsx
···11+import { H2, View } from "tamagui";
12import pkg from "../../package.json";
22-import { View, H2 } from "tamagui";
3344// maybe someday some PWA update stuff will live here
55export function Updates() {
+2-2
js/app/components/sidebar/sidebar-item.tsx
···11import { FileQuestion } from "@tamagui/lucide-icons";
22-import { Text, View, AnimatePresence } from "tamagui";
33-import { Pressable } from "react-native-gesture-handler";
42import { ReactNode, useState } from "react";
53import { PressableStateCallbackType, StyleProp, ViewStyle } from "react-native";
44+import { Pressable } from "react-native-gesture-handler";
55+import { AnimatePresence, Text, View } from "tamagui";
6677export default function SidebarItem({
88 icon,
+6-6
js/app/components/sidebar/sidebar.tsx
···11-import { YStack, styled, Text, View, Image } from "tamagui";
22-import { SharedValue, useAnimatedStyle } from "react-native-reanimated";
33-import SidebarItem from "./sidebar-item";
11+import { DrawerNavigationOptions } from "@react-navigation/drawer";
22+import { DrawerDescriptorMap } from "@react-navigation/drawer/lib/typescript/src/types";
43import {
54 CommonActions,
65 DrawerNavigationState,
76 ParamListBase,
87} from "@react-navigation/native";
99-import { DrawerNavigationOptions } from "@react-navigation/drawer";
1010-import { DrawerDescriptorMap } from "@react-navigation/drawer/lib/typescript/src/types";
88+import { FileQuestion } from "@tamagui/lucide-icons";
119import { Platform } from "react-native";
1212-import { FileQuestion } from "@tamagui/lucide-icons";
1010+import { SharedValue, useAnimatedStyle } from "react-native-reanimated";
1111+import { Image, styled, Text, View, YStack } from "tamagui";
1212+import SidebarItem from "./sidebar-item";
13131414const AnimatedYStack = styled(YStack, {
1515 name: "AnimatedYStack",
···11+import { Camera, Image as ImageIcon, X } from "@tamagui/lucide-icons";
12import { useCallback, useEffect, useRef, useState } from "react";
23import { Button, Image, Text, View, isWeb } from "tamagui";
33-import { Camera, Image as ImageIcon, X } from "@tamagui/lucide-icons";
44import { ThumbnailSelectorProps } from "./shared";
5566export default function ThumbnailSelector({
+2-2
js/app/components/timer.tsx
···11-import { View, Text } from "tamagui";
22-import { useState, useEffect } from "react";
11+import { useEffect, useState } from "react";
22+import { Text, View } from "tamagui";
3344export default function Timer({ start }: { start: string | Date }) {
55 const [elapsedTime, setElapsedTime] = useState(0);
+1-1
js/app/components/ui/button-selector.tsx
···11-import { YStack, XStack, Text, Button, View, YStackProps } from "tamagui";
11+import { Button, Text, XStack, YStack, YStackProps } from "tamagui";
2233export default function ButtonSelector({
44 text,
+1-1
js/app/components/viewers.tsx
···11import { User } from "@tamagui/lucide-icons";
22-import { View, Text } from "tamagui";
22+import { Text, View } from "tamagui";
3344export default function Viewers({ viewers }: { viewers: number }) {
55 return (
+2-2
js/app/contexts/FullscreenContext.tsx
···44} from "features/base/sidebarSlice";
55import {
66 createContext,
77- useContext,
88- useState,
97 ReactNode,
88+ useContext,
109 useEffect,
1010+ useState,
1111} from "react";
1212import { useDispatch } from "react-redux";
1313
···11import { Agent } from "@atproto/api";
22+import { schemas as parentSchemas } from "@atproto/api/dist/client/lexicons";
23import { SessionManager } from "@atproto/api/dist/session-manager";
33-import { PlaceNS } from "streamplace";
44-import { schemas as parentSchemas } from "@atproto/api/dist/client/lexicons";
55-import { schemas as appSchemas } from "streamplace";
64import { Lexicons } from "@atproto/lexicon";
55+import { schemas as appSchemas, PlaceNS } from "streamplace";
76export class StreamplaceAgent extends Agent {
87 place = new PlaceNS(this);
98 lex: Lexicons;
···11+import Loading from "components/loading/loading";
12import { createContext, useEffect } from "react";
22-import { DEFAULT_URL, initialize, selectStreamplace } from "./streamplaceSlice";
33import { useAppDispatch, useAppSelector } from "store/hooks";
44-import Loading from "components/loading/loading";
55-import { View, Text } from "tamagui";
44+import { Text, View } from "tamagui";
55+import { DEFAULT_URL, initialize, selectStreamplace } from "./streamplaceSlice";
6677export const StreamplaceContext = createContext({
88 url: DEFAULT_URL,
+2-3
js/app/features/streamplace/streamplaceSlice.tsx
···11+import { BlueskyState } from "features/bluesky/blueskyTypes";
22+import { PlaceStreamLivestream, PlaceStreamSegment } from "streamplace";
13import { isWeb } from "tamagui";
24import { createAppSlice } from "../../hooks/createSlice";
35import Storage from "../../storage";
44-import { BlueskyState } from "features/bluesky/blueskyTypes";
55-import { PlaceStreamSegment, PlaceStreamLivestream } from "streamplace";
66-import { StreamplaceAgent } from "features/bluesky/agent";
7687let DEFAULT_URL = process.env.EXPO_PUBLIC_STREAMPLACE_URL as string;
98if (isWeb && process.env.EXPO_PUBLIC_WEB_TRY_LOCAL === "true") {
+3-3
js/app/hooks/useAvatars.tsx
···11-import { useEffect, useMemo } from "react";
21import { ProfileViewDetailed } from "@atproto/api/dist/client/types/app/bsky/actor/defs";
33-import { useAppSelector, useAppDispatch } from "store/hooks";
42import {
55- selectCachedProfiles,
63 getProfiles,
44+ selectCachedProfiles,
75} from "features/bluesky/blueskySlice";
66+import { useEffect, useMemo } from "react";
77+import { useAppDispatch, useAppSelector } from "store/hooks";
8899// Hack: Easy way to cache and get avatars
1010export default function useAvatars(dids: string[]) {
+1-1
js/app/hooks/useCaptureVideoFrame.ts
···11+import { useVideoElement } from "contexts/VideoElementContext";
12import { useCallback } from "react";
23import { isWeb } from "tamagui";
33-import { useVideoElement } from "contexts/VideoElementContext";
44import { captureVideoFrame } from "utils/videoCapture";
5566/**
+1-1
js/app/hooks/usePreloadEmoji.ts
···11-import React from "react";
21import { init } from "emoji-mart";
22+import React from "react";
33import { isWeb } from "tamagui";
4455let loadRequested = false;
+3-3
js/app/hooks/useSidebarControl.tsx
···44 useSharedValue,
55 withTiming,
66} from "react-native-reanimated";
77-import { useWindowDimensions } from "tamagui";
87import { useDispatch, useSelector } from "react-redux";
88+import { useWindowDimensions } from "tamagui";
991010import {
1111- toggleSidebar,
1211 selectIsSidebarCollapsed,
1212+ selectIsSidebarHidden,
1313 selectSidebarTargetWidth,
1414- selectIsSidebarHidden,
1414+ toggleSidebar,
1515} from "../features/base/sidebarSlice";
1616import { RootState } from "../store/store";
1717
+1-1
js/app/hooks/useWallet.shared.tsx
···11-import { TypedData, SignTypedDataParameters } from "viem";
11+import { SignTypedDataParameters, TypedData } from "viem";
2233export type SignTypedDataFn = <
44 const typedData extends TypedData | { [key: string]: unknown },
+6-7
js/app/hooks/useWallet.tsx
···11-import { createContext, useContext, useEffect, useState } from "react";
22-import { createWalletClient, http } from "viem";
33-import usePlatform from "./usePlatform";
41import {
52 ConnectButton,
63 getDefaultConfig,
74 RainbowKitProvider,
85} from "@rainbow-me/rainbowkit";
99-import React from "react";
66+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
77+import React, { createContext, useContext, useEffect, useState } from "react";
108import { View as RNView, View } from "react-native";
99+import { Paragraph } from "tamagui";
1010+import { createWalletClient, http } from "viem";
1111import { privateKeyToAccount } from "viem/accounts";
1212import { arbitrum, base, mainnet, optimism, polygon } from "viem/chains";
1313-import { Paragraph } from "tamagui";
1414-import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
1313+import usePlatform from "./usePlatform";
1514import {
1615 notActiveWallet,
1616+ SignTypedDataFn,
1717 WalletStuff,
1818- SignTypedDataFn,
1918} from "./useWallet.shared";
20192120const WalletContext = createContext(notActiveWallet);
+1-1
js/app/src/entrypoint.tsx
···22// hot module reloading works properly on web.
3344import "@expo/metro-runtime";
55+import { registerRootComponent } from "expo";
56import "./polyfills";
67import Router from "./router";
77-import { registerRootComponent } from "expo";
8899registerRootComponent(Router);
+33-33
js/app/src/router.tsx
···1616import { createNativeStackNavigator } from "@react-navigation/native-stack";
1717import {
1818 ArrowLeft,
1919+ Book,
2020+ Download,
2121+ ExternalLink,
1922 Home,
2023 LogIn,
2124 Menu,
2525+ Notebook,
2626+ PanelLeftClose,
2727+ PanelLeftOpen,
2228 Settings as SettingsIcon,
2323- User,
2429 ShieldQuestion,
2525- Download,
3030+ User,
2631 Video,
2727- PanelLeftOpen,
2828- PanelLeftClose,
2929- Book,
3030- ExternalLink,
3131- Notebook,
3232} from "@tamagui/lucide-icons";
3333+import { useToastController } from "@tamagui/toast";
3334import { Provider, Settings } from "components";
3435import AQLink from "components/aqlink";
3536import Login from "components/login/login";
3737+import Popup from "components/popup";
3838+import Sidebar, { ExternalDrawerItem } from "components/sidebar/sidebar";
3939+import { hydrate, selectHydrated } from "features/base/baseSlice";
3640import { selectUserProfile } from "features/bluesky/blueskySlice";
4141+import {
4242+ clearNotification,
4343+ initPushNotifications,
4444+ registerNotificationToken,
4545+ selectNotificationDestination,
4646+ selectNotificationToken,
4747+} from "features/platform/platformSlice.native";
4848+import {
4949+ pollMySegments,
5050+ pollSegments,
5151+} from "features/streamplace/streamplaceSlice";
5252+import { useLiveUser } from "hooks/useLiveUser";
3753import usePlatform from "hooks/usePlatform";
5454+import { useSidebarControl } from "hooks/useSidebarControl";
3855import { ReactElement, useEffect, useState } from "react";
3956import {
4057 ImageBackground,
···4562 StatusBar,
4663} from "react-native";
4764import { useAppDispatch, useAppSelector } from "store/hooks";
4848-import { useTheme, Text, View, H3 } from "tamagui";
4949-import AppReturnScreen from "./screens/app-return";
5050-import MultiScreen from "./screens/multi";
5151-import StreamScreen from "./screens/stream";
5252-import SupportScreen from "./screens/support";
6565+import { H3, Text, useTheme, View } from "tamagui";
5366import AboutScreen from "./screens/about";
5454-import DownloadScreen from "./screens/download";
5555-import { hydrate, selectHydrated } from "features/base/baseSlice";
6767+import AppReturnScreen from "./screens/app-return";
5668import AVSyncScreen from "./screens/av-sync";
5757-import {
5858- clearNotification,
5959- initPushNotifications,
6060- registerNotificationToken,
6161- selectNotificationDestination,
6262- selectNotificationToken,
6363-} from "features/platform/platformSlice.native";
6464-import {
6565- pollMySegments,
6666- pollSegments,
6767-} from "features/streamplace/streamplaceSlice";
6868-import { useLiveUser } from "hooks/useLiveUser";
6969-import { useToastController } from "@tamagui/toast";
7070-import LiveDashboard from "./screens/live-dashboard";
7171-import Popup from "components/popup";
7269import PopoutChat from "./screens/chat-popout";
7070+import DownloadScreen from "./screens/download";
7371import EmbedScreen from "./screens/embed";
7474-import { useSidebarControl } from "hooks/useSidebarControl";
7575-import Sidebar, { ExternalDrawerItem } from "components/sidebar/sidebar";
7272+import LiveDashboard from "./screens/live-dashboard";
7373+import MultiScreen from "./screens/multi";
7474+import StreamScreen from "./screens/stream";
7575+import SupportScreen from "./screens/support";
76767777// probabl should move this
7878-import { store } from "store/store";
7878+import SignUp from "components/login/signup";
7979import { loadStateFromStorage } from "features/base/sidebarSlice";
8080+import { store } from "store/store";
8081import HomeScreen from "./screens/home";
8181-import SignUp from "components/login/signup";
82828383store.dispatch(loadStateFromStorage());
8484
+1-1
js/app/src/screens/about.tsx
···11-import { H4 as TamaguiH4, Paragraph, View, Anchor } from "tamagui";
11+import { Anchor, Paragraph, H4 as TamaguiH4, View } from "tamagui";
2233const H4 = (props: any) => <TamaguiH4 fontWeight="100" {...props} />;
44const P = (props: any) => (
+4-4
js/app/src/screens/av-sync.tsx
···11-import { useEffect, useRef } from "react";
22-import { View } from "tamagui";
33-import QRCode from "qrcode";
41import { Countdown } from "components";
55-import { str2ab } from "quietjs-bundle";
62import { QUIET_PROFILE } from "components/player/av-sync";
33+import QRCode from "qrcode";
44+import { str2ab } from "quietjs-bundle";
55+import { useEffect, useRef } from "react";
66+import { View } from "tamagui";
7788// screen that displays timestamp as a QR code and encodes timestamp in audio
99// so we can measure sync between them
+1-1
js/app/src/screens/download.tsx
···11-import { H4 as TamaguiH4, Paragraph, View, Anchor } from "tamagui";
11+import { Anchor, Paragraph, H4 as TamaguiH4, View } from "tamagui";
22import GetApps from "../../components/get-apps";
3344const H4 = (props: any) => <TamaguiH4 fontWeight="100" {...props} />;
+1-1
js/app/src/screens/embed.tsx
···11+import { Player } from "components";
12import { PlayerProps } from "components/player/props";
23import { isWeb } from "tamagui";
34import { queryToProps } from "./util";
44-import { Player } from "components";
5566export default function EmbedScreen({ route }) {
77 const { user, protocol, url } = route.params;
+8-9
js/app/src/screens/home.tsx
···11+import { AlertCircle } from "@tamagui/lucide-icons";
12import { UseMediaState } from "@tamagui/web";
23import AQLink from "components/aqlink";
44+import Container from "components/container";
35import ErrorBox from "components/error/error";
44-import Loading from "components/loading/loading";
56import StreamCardHorizontal, { StreamCardSize } from "components/home/cards";
66-import Container from "components/container";
77import LiveDot from "components/home/live-dot";
88+import Loading from "components/loading/loading";
89import Title from "components/title";
910import {
1011 pollSegments,
1111- Repo,
1212 selectRecentSegments,
1313} from "features/streamplace/streamplaceSlice";
1414import useAvatars from "hooks/useAvatars";
···1616import { useEffect, useState } from "react";
1717import { RefreshControl } from "react-native";
1818import { useAppDispatch, useAppSelector } from "store/hooks";
1919+import { PlaceStreamLivestream } from "streamplace";
1920import {
2121+ H3,
2222+ Image,
2323+ Paragraph,
2024 ScrollView,
2125 ScrollViewProps,
2626+ Text,
2227 useMedia,
2328 View,
2424- Image,
2525- Paragraph,
2626- H3,
2727- Text,
2829} from "tamagui";
2929-import { LivestreamRecord, PlaceStreamLivestream } from "streamplace";
3030-import { AlertCircle, AlertTriangle } from "@tamagui/lucide-icons";
31303231// as we're not using a specific grid library these are necessary
3332// to constrain the cards
+12-13
js/app/src/screens/live-dashboard.tsx
···11+import { Camera, FerrisWheel, X } from "@tamagui/lucide-icons";
22+import { Redirect } from "components/aqlink";
13import CreateLivestream from "components/create-livestream";
22-import { Button, isWeb, View } from "tamagui";
44+import UpdateLivestream from "components/edit-livestream";
55+import StreamKeyScreen from "components/live-dashboard/stream-key";
66+import Waiting from "components/live-dashboard/waiting";
77+import Loading from "components/loading/loading";
38import { Player } from "components/player/player";
44-import Loading from "components/loading/loading";
99+import ButtonSelector from "components/ui/button-selector";
1010+import { VideoElementProvider } from "contexts/VideoElementContext";
511import {
612 selectIsReady,
713 selectUserProfile,
814} from "features/bluesky/blueskySlice";
1515+import { selectTelemetry } from "features/streamplace/streamplaceSlice";
1616+import { useLiveUser } from "hooks/useLiveUser";
1717+import React, { useCallback, useState } from "react";
918import { useAppSelector } from "store/hooks";
1010-import { Redirect } from "components/aqlink";
1111-import React, { useCallback, useState } from "react";
1212-import { useLiveUser } from "hooks/useLiveUser";
1313-import StreamKeyScreen from "components/live-dashboard/stream-key";
1414-import { VideoElementProvider } from "contexts/VideoElementContext";
1515-import { Camera, FerrisWheel, X } from "@tamagui/lucide-icons";
1616-import { H6, Text } from "tamagui";
1717-import Waiting from "components/live-dashboard/waiting";
1818-import { selectTelemetry } from "features/streamplace/streamplaceSlice";
1919-import UpdateLivestream from "components/edit-livestream";
2020-import ButtonSelector from "components/ui/button-selector";
1919+import { Button, H6, isWeb, Text, View } from "tamagui";
21202221enum StreamSource {
2322 Start,
+2-2
js/app/src/screens/stream.tsx
···11+import Livestream from "components/livestream/livestream";
12import { PlayerProps } from "components/player/props";
33+import { FullscreenProvider } from "contexts/FullscreenContext";
24import { isWeb } from "tamagui";
35import { queryToProps } from "./util";
44-import Livestream from "components/livestream/livestream";
55-import { FullscreenProvider } from "contexts/FullscreenContext";
6677export default function StreamScreen({ route }) {
88 const { user, protocol, url } = route.params;
+1-1
js/app/storage/storage.native.tsx
···11import Storage from "expo-sqlite/kv-store";
22-import { AQStorage } from "./storage.shared";
32import { Lock } from "./lock";
33+import { AQStorage } from "./storage.shared";
4455// Needed because concurrent calls seem to return with a locked database
66const lock = new Lock();
+1-1
js/app/store/listener.ts
···11import { createListenerMiddleware, isAnyOf } from "@reduxjs/toolkit";
22import { SIDEBAR_STORAGE_KEY, sidebarSlice } from "features/base/sidebarSlice";
33-import { RootState } from "./store";
43import storage from "storage";
44+import { RootState } from "./store";
5566export const listenerMiddleware = createListenerMiddleware();
77
+2-2
js/app/store/store.tsx
···11import type { Action, ThunkAction } from "@reduxjs/toolkit";
22import { combineSlices, configureStore } from "@reduxjs/toolkit";
33import { setupListeners } from "@reduxjs/toolkit/query";
44-import { streamplaceSlice } from "features/streamplace/streamplaceSlice";
54import { baseSlice } from "features/base/baseSlice";
55+import { sidebarSlice } from "features/base/sidebarSlice";
66import { blueskySlice } from "features/bluesky/blueskySlice";
77import { platformSlice } from "features/platform/platformSlice";
88import { playerSlice } from "features/player/playerSlice";
99-import { sidebarSlice } from "features/base/sidebarSlice";
99+import { streamplaceSlice } from "features/streamplace/streamplaceSlice";
10101111import { listenerMiddleware } from "./listener";
1212
+1-1
js/app/tamagui.config.ts
···11import { config as configBase } from "@tamagui/config/v3";
22-import { createTamagui, createFont } from "tamagui";
22+import { createFont, createTamagui } from "tamagui";
3344const sizes = {
55 "1": 11,
+1-1
js/app/utils/videoCapture.ts
···11/**
22 * Utility functions for capturing video frames
33 */
44-import { isWeb } from "tamagui";
54import React from "react";
55+import { isWeb } from "tamagui";
6677/**
88 * Captures a frame from a video ref or element and returns it as a compressed JPEG blob
···11import { app, dialog, ipcMain } from "electron";
22import { parseArgs } from "node:util";
33import "source-map-support/register";
44+import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
45import getEnv from "./env";
56import makeNode from "./node";
77+import runTests, { allTestNames } from "./tests/test-runner";
68import initUpdater from "./updater";
77-import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
89import { makeWindow } from "./window";
99-import runTests from "./tests/test-runner";
1010-import { allTestNames } from "./tests/test-runner";
11101211// Handle creating/removing shortcuts on Windows when installing/uninstalling.
1312if (require("electron-squirrel-startup")) {
+3-3
js/desktop/src/node.ts
···11+import { spawn } from "child_process";
22+import { app } from "electron";
33+import { access, constants } from "fs/promises";
14import os from "os";
25import { resolve } from "path";
33-import { access, constants } from "fs/promises";
44-import { spawn } from "child_process";
56import getEnv from "./env";
66-import { app } from "electron";
7788const findExe = async (): Promise<string> => {
99 const { isDev } = getEnv();
+1-1
js/desktop/src/tests/playback-test.ts
···11-import { delay, PlayerReport } from "./util";
21import { v7 as uuidv7 } from "uuid";
32import { makeWindow } from "../window";
43import { E2ETest, TestEnv } from "./test-env";
44+import { delay, PlayerReport } from "./util";
5566const PLAYING_SUCCESS = 0.5;
77
+3-3
js/desktop/src/tests/sync-test.ts
···11-import { BrowserWindow, WebFrameMain, webFrameMain, session } from "electron";
11+import { BrowserWindow, session, WebFrameMain, webFrameMain } from "electron";
22+import { v7 as uuidv7 } from "uuid";
23import { MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY } from "../env";
33-import { delay, PlayerReport } from "./util";
44import { E2ETest, TestEnv } from "./test-env";
55-import { v7 as uuidv7 } from "uuid";
55+import { delay, PlayerReport } from "./util";
6677const SYNC_TOO_FAR = 20000;
88
+5-5
js/desktop/src/tests/test-runner.ts
···11import { bytesToMultibase } from "@atproto/crypto";
22+import { ChildProcess } from "child_process";
33+import fs from "fs/promises";
44+import os from "os";
55+import path from "path";
66+import { privateKeyToAccount } from "viem/accounts";
27import getEnv from "../env";
38import makeNode from "../node";
49import { playbackTest } from "./playback-test";
510import { syncTest } from "./sync-test";
611import { E2ETest, TestEnv } from "./test-env";
77-import { ChildProcess } from "child_process";
88-import { privateKeyToAccount } from "viem/accounts";
99-import fs from "fs/promises";
1010-import path from "path";
1111-import os from "os";
12121313const allTests: Record<string, E2ETest> = {
1414 playback: playbackTest,
+3-3
js/desktop/src/updater.ts
···11+import electron from "electron";
22+import ms from "ms";
13import {
24 IUpdateElectronAppOptions,
35 UpdateSourceType,
46} from "update-electron-app";
55-import electron from "electron";
66-import ms from "ms";
77-import * as build from "./version";
87import env from "./env";
88+import * as build from "./version";
991010const supportedPlatforms = ["darwin", "win32"];
1111