about summary refs log tree commit diff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ThemeContext.tsx28
-rw-r--r--src/lib/api/feed-manip.ts17
-rw-r--r--src/lib/hooks/useAuxClick.ts2
-rw-r--r--src/lib/hooks/useAuxClick.web.ts43
-rw-r--r--src/lib/media/manip.web.ts3
-rw-r--r--src/lib/strings/embed-player.ts13
-rw-r--r--src/lib/strings/password.ts19
-rw-r--r--src/lib/themes.ts13
8 files changed, 72 insertions, 66 deletions
diff --git a/src/lib/ThemeContext.tsx b/src/lib/ThemeContext.tsx
index 38bd199cb..63e2beeb1 100644
--- a/src/lib/ThemeContext.tsx
+++ b/src/lib/ThemeContext.tsx
@@ -1,11 +1,7 @@
 import React, {ReactNode, createContext, useContext} from 'react'
-import {
-  TextStyle,
-  useColorScheme,
-  ViewStyle,
-  ColorSchemeName,
-} from 'react-native'
-import {darkTheme, defaultTheme} from './themes'
+import {TextStyle, ViewStyle} from 'react-native'
+import {darkTheme, defaultTheme, dimTheme} from './themes'
+import {ThemeName} from '#/alf/themes'
 
 export type ColorScheme = 'light' | 'dark'
 
@@ -84,23 +80,31 @@ export interface Theme {
 
 export interface ThemeProviderProps {
   children?: ReactNode
-  theme?: 'light' | 'dark' | 'system'
+  theme: ThemeName
 }
 
 export const ThemeContext = createContext<Theme>(defaultTheme)
 
 export const useTheme = () => useContext(ThemeContext)
 
-function getTheme(theme: ColorSchemeName) {
-  return theme === 'dark' ? darkTheme : defaultTheme
+function getTheme(theme: ThemeName) {
+  switch (theme) {
+    case 'light':
+      return defaultTheme
+    case 'dim':
+      return dimTheme
+    case 'dark':
+      return darkTheme
+    default:
+      return defaultTheme
+  }
 }
 
 export const ThemeProvider: React.FC<ThemeProviderProps> = ({
   theme,
   children,
 }) => {
-  const colorScheme = useColorScheme()
-  const themeValue = getTheme(theme === 'system' ? colorScheme : theme)
+  const themeValue = getTheme(theme)
 
   return (
     <ThemeContext.Provider value={themeValue}>{children}</ThemeContext.Provider>
diff --git a/src/lib/api/feed-manip.ts b/src/lib/api/feed-manip.ts
index c964693c4..227062592 100644
--- a/src/lib/api/feed-manip.ts
+++ b/src/lib/api/feed-manip.ts
@@ -168,14 +168,25 @@ export class FeedTuner {
 
         const selfReplyUri = getSelfReplyUri(item)
         if (selfReplyUri) {
-          const parent = slices.find(item2 =>
-            item2.isNextInThread(selfReplyUri),
+          const index = slices.findIndex(slice =>
+            slice.isNextInThread(selfReplyUri),
           )
-          if (parent) {
+
+          if (index !== -1) {
+            const parent = slices[index]
+
             parent.insert(item)
+
+            // If our slice isn't currently on the top, reinsert it to the top.
+            if (index !== 0) {
+              slices.splice(index, 1)
+              slices.unshift(parent)
+            }
+
             continue
           }
         }
+
         slices.unshift(new FeedViewPostsSlice([item]))
       }
     }
diff --git a/src/lib/hooks/useAuxClick.ts b/src/lib/hooks/useAuxClick.ts
deleted file mode 100644
index ab6fd4365..000000000
--- a/src/lib/hooks/useAuxClick.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-// does nothing in native
-export const useAuxClick = () => {}
diff --git a/src/lib/hooks/useAuxClick.web.ts b/src/lib/hooks/useAuxClick.web.ts
deleted file mode 100644
index ca9811615..000000000
--- a/src/lib/hooks/useAuxClick.web.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import {useEffect} from 'react'
-
-// This is the handler for the middle mouse button click on the feed.
-// Normally, we would do this via `onAuxClick` handler on each link element
-// However, that handler is not supported on react-native-web and there are some
-// discrepancies between various browsers (i.e: safari doesn't trigger it and routes through click event)
-// So, this temporary alternative is meant to bridge the gap in an efficient way until the support improves.
-export const useAuxClick = () => {
-  const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
-  useEffect(() => {
-    // On the web, it should always be there but in case it gets accidentally included in native builds
-    const wrapperEl = document?.body
-
-    // Safari already handles auxclick event as click+metaKey so we need to avoid doing this there in case it becomes recursive
-    if (wrapperEl && !isSafari) {
-      const handleAuxClick = (e: MouseEvent & {target: HTMLElement}) => {
-        // Only handle the middle mouse button click
-        // Only handle if the clicked element itself or one of its ancestors is a link
-        if (
-          e.button !== 1 ||
-          e.target.closest('a') ||
-          e.target.tagName === 'A'
-        ) {
-          return
-        }
-
-        // On the original element, trigger a click event with metaKey set to true so that it triggers
-        // the browser's default behavior of opening the link in a new tab
-        e.target.dispatchEvent(
-          new MouseEvent('click', {metaKey: true, bubbles: true}),
-        )
-      }
-
-      // @ts-ignore For web only
-      wrapperEl.addEventListener('auxclick', handleAuxClick)
-
-      return () => {
-        // @ts-ignore For web only
-        wrapperEl?.removeEventListener('auxclick', handleAuxClick)
-      }
-    }
-  }, [isSafari])
-}
diff --git a/src/lib/media/manip.web.ts b/src/lib/media/manip.web.ts
index bdf6836a1..522aa2e51 100644
--- a/src/lib/media/manip.web.ts
+++ b/src/lib/media/manip.web.ts
@@ -132,6 +132,9 @@ function createResizedImage(
       ctx.drawImage(img, 0, 0, w, h)
       resolve(canvas.toDataURL('image/jpeg', quality))
     })
+    img.addEventListener('error', ev => {
+      reject(ev.error)
+    })
     img.src = dataUri
   })
 }
diff --git a/src/lib/strings/embed-player.ts b/src/lib/strings/embed-player.ts
index 3270b6f07..21a575b91 100644
--- a/src/lib/strings/embed-player.ts
+++ b/src/lib/strings/embed-player.ts
@@ -1,4 +1,5 @@
-import {Dimensions, Platform} from 'react-native'
+import {Dimensions} from 'react-native'
+import {isWeb} from 'platform/detection'
 const {height: SCREEN_HEIGHT} = Dimensions.get('window')
 
 export const embedPlayerSources = [
@@ -73,7 +74,7 @@ export function parseEmbedPlayerFromUrl(
       return {
         type: 'youtube_video',
         source: 'youtube',
-        playerUri: `https://www.youtube.com/embed/${videoId}?autoplay=1&playsinline=1&start=${seek}`,
+        playerUri: `https://bsky.app/iframe/youtube.html?videoId=${videoId}&start=${seek}`,
       }
     }
   }
@@ -92,7 +93,7 @@ export function parseEmbedPlayerFromUrl(
         type: page === 'shorts' ? 'youtube_short' : 'youtube_video',
         source: page === 'shorts' ? 'youtubeShorts' : 'youtube',
         hideDetails: page === 'shorts' ? true : undefined,
-        playerUri: `https://www.youtube.com/embed/${videoId}?autoplay=1&playsinline=1&start=${seek}`,
+        playerUri: `https://bsky.app/iframe/youtube.html?videoId=${videoId}&start=${seek}`,
       }
     }
   }
@@ -103,8 +104,10 @@ export function parseEmbedPlayerFromUrl(
     urlp.hostname === 'www.twitch.tv' ||
     urlp.hostname === 'm.twitch.tv'
   ) {
-    const parent =
-      Platform.OS === 'web' ? window.location.hostname : 'localhost'
+    const parent = isWeb
+      ? // @ts-ignore only for web
+        window.location.hostname
+      : 'localhost'
 
     const [_, channelOrVideo, clipOrId, id] = urlp.pathname.split('/')
 
diff --git a/src/lib/strings/password.ts b/src/lib/strings/password.ts
new file mode 100644
index 000000000..e7735b90e
--- /dev/null
+++ b/src/lib/strings/password.ts
@@ -0,0 +1,19 @@
+// Regex for base32 string for testing reset code
+const RESET_CODE_REGEX = /^[A-Z2-7]{5}-[A-Z2-7]{5}$/
+
+export function checkAndFormatResetCode(code: string): string | false {
+  // Trim the reset code
+  let fixed = code.trim().toUpperCase()
+
+  // Add a dash if needed
+  if (fixed.length === 10) {
+    fixed = `${fixed.slice(0, 5)}-${fixed.slice(5, 10)}`
+  }
+
+  // Check that it is a valid format
+  if (!RESET_CODE_REGEX.test(fixed)) {
+    return false
+  }
+
+  return fixed
+}
diff --git a/src/lib/themes.ts b/src/lib/themes.ts
index 2d4515c77..9a3880b92 100644
--- a/src/lib/themes.ts
+++ b/src/lib/themes.ts
@@ -2,7 +2,7 @@ import {Platform} from 'react-native'
 import type {Theme} from './ThemeContext'
 import {colors} from './styles'
 
-import {darkPalette, lightPalette} from '#/alf/themes'
+import {darkPalette, lightPalette, dimPalette} from '#/alf/themes'
 
 export const defaultTheme: Theme = {
   colorScheme: 'light',
@@ -336,3 +336,14 @@ export const darkTheme: Theme = {
     },
   },
 }
+
+export const dimTheme: Theme = {
+  ...darkTheme,
+  palette: {
+    ...darkTheme.palette,
+    default: {
+      ...darkTheme.palette.default,
+      background: dimPalette.black,
+    },
+  },
+}