aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2026-02-01 19:43:32 +0000
committerMohamed Bassem <me@mbassem.com>2026-02-01 19:43:32 +0000
commite86188000147e0178ac6ca971f061b37daa40132 (patch)
tree654b20fd932d9ca4f93ef4e2bfc85ff6d9fd624c
parentb16fa5e21a3852151c6b3d3d5569154d863d1795 (diff)
downloadkarakeep-e86188000147e0178ac6ca971f061b37daa40132.tar.zst
fix(mobile): migrate from RN image to expo-image
-rw-r--r--apps/mobile/components/bookmarks/BookmarkAssetImage.tsx15
-rw-r--r--apps/mobile/components/bookmarks/BookmarkAssetView.tsx2
-rw-r--r--apps/mobile/components/bookmarks/BookmarkCard.tsx52
-rw-r--r--apps/mobile/components/bookmarks/BookmarkLinkPreview.tsx3
-rw-r--r--apps/mobile/components/ui/Avatar.tsx9
-rw-r--r--apps/mobile/lib/hooks.ts8
6 files changed, 55 insertions, 34 deletions
diff --git a/apps/mobile/components/bookmarks/BookmarkAssetImage.tsx b/apps/mobile/components/bookmarks/BookmarkAssetImage.tsx
index 8fa88c8b..35726e4b 100644
--- a/apps/mobile/components/bookmarks/BookmarkAssetImage.tsx
+++ b/apps/mobile/components/bookmarks/BookmarkAssetImage.tsx
@@ -1,14 +1,25 @@
-import { Image } from "react-native";
+import { View } from "react-native";
+import { Image, ImageContentFit } from "expo-image";
import { useAssetUrl } from "@/lib/hooks";
export default function BookmarkAssetImage({
assetId,
className,
+ contentFit = "cover",
}: {
assetId: string;
className: string;
+ contentFit?: ImageContentFit;
}) {
const assetSource = useAssetUrl(assetId);
- return <Image source={assetSource} className={className} />;
+ return (
+ <View className={className}>
+ <Image
+ source={assetSource}
+ style={{ width: "100%", height: "100%" }}
+ contentFit={contentFit}
+ />
+ </View>
+ );
}
diff --git a/apps/mobile/components/bookmarks/BookmarkAssetView.tsx b/apps/mobile/components/bookmarks/BookmarkAssetView.tsx
index 5fe2f470..e009a027 100644
--- a/apps/mobile/components/bookmarks/BookmarkAssetView.tsx
+++ b/apps/mobile/components/bookmarks/BookmarkAssetView.tsx
@@ -48,7 +48,7 @@ export default function BookmarkAssetView({
<Pressable onPress={() => setImageZoom(true)}>
<BookmarkAssetImage
assetId={bookmark.content.assetId}
- className="h-56 min-h-56 w-full object-cover"
+ className="h-56 min-h-56 w-full"
/>
</Pressable>
</View>
diff --git a/apps/mobile/components/bookmarks/BookmarkCard.tsx b/apps/mobile/components/bookmarks/BookmarkCard.tsx
index 41e57f89..cd0ea445 100644
--- a/apps/mobile/components/bookmarks/BookmarkCard.tsx
+++ b/apps/mobile/components/bookmarks/BookmarkCard.tsx
@@ -1,7 +1,6 @@
import {
ActivityIndicator,
Alert,
- Image,
Platform,
Pressable,
ScrollView,
@@ -11,6 +10,7 @@ import {
import * as Clipboard from "expo-clipboard";
import * as FileSystem from "expo-file-system/legacy";
import * as Haptics from "expo-haptics";
+import { Image } from "expo-image";
import { router, useRouter } from "expo-router";
import * as Sharing from "expo-sharing";
import { Text } from "@/components/ui/Text";
@@ -317,30 +317,36 @@ function LinkCard({
let imageComp;
if (imageUrl) {
imageComp = (
- <Image
- source={
- imageUrl.localAsset
- ? {
- uri: `${settings.address}${imageUrl.url}`,
- headers: buildApiHeaders(
- settings.apiKey,
- settings.customHeaders,
- ),
- }
- : {
- uri: imageUrl.url,
- }
- }
- className="h-56 min-h-56 w-full object-cover"
- />
+ <View className="h-56 min-h-56 w-full">
+ <Image
+ source={
+ imageUrl.localAsset
+ ? {
+ uri: `${settings.address}${imageUrl.url}`,
+ headers: buildApiHeaders(
+ settings.apiKey,
+ settings.customHeaders,
+ ),
+ }
+ : {
+ uri: imageUrl.url,
+ }
+ }
+ style={{ width: "100%", height: "100%" }}
+ contentFit="cover"
+ />
+ </View>
);
} else {
imageComp = (
- <Image
- // oxlint-disable-next-line no-require-imports
- source={require("@/assets/blur.jpeg")}
- className="h-56 w-full rounded-t-lg"
- />
+ <View className="h-56 w-full overflow-hidden rounded-t-lg">
+ <Image
+ // oxlint-disable-next-line no-require-imports
+ source={require("@/assets/blur.jpeg")}
+ style={{ width: "100%", height: "100%" }}
+ contentFit="cover"
+ />
+ </View>
);
}
@@ -444,7 +450,7 @@ function AssetCard({
<Pressable onPress={onOpenBookmark}>
<BookmarkAssetImage
assetId={assetImage}
- className="h-56 min-h-56 w-full object-cover"
+ className="h-56 min-h-56 w-full"
/>
</Pressable>
<View className="flex gap-2 p-2">
diff --git a/apps/mobile/components/bookmarks/BookmarkLinkPreview.tsx b/apps/mobile/components/bookmarks/BookmarkLinkPreview.tsx
index fe27836a..57e00c24 100644
--- a/apps/mobile/components/bookmarks/BookmarkLinkPreview.tsx
+++ b/apps/mobile/components/bookmarks/BookmarkLinkPreview.tsx
@@ -228,7 +228,8 @@ export function BookmarkLinkScreenshotPreview({
<Pressable onPress={() => setImageZoom(true)}>
<BookmarkAssetImage
assetId={asset.id}
- className="h-full w-full object-contain"
+ className="h-full w-full"
+ contentFit="contain"
/>
</Pressable>
</View>
diff --git a/apps/mobile/components/ui/Avatar.tsx b/apps/mobile/components/ui/Avatar.tsx
index 923c634e..ed31df23 100644
--- a/apps/mobile/components/ui/Avatar.tsx
+++ b/apps/mobile/components/ui/Avatar.tsx
@@ -1,5 +1,6 @@
import * as React from "react";
-import { Image, View } from "react-native";
+import { View } from "react-native";
+import { Image } from "expo-image";
import { Text } from "@/components/ui/Text";
import { useAssetUrl } from "@/lib/hooks";
import { cn } from "@/lib/utils";
@@ -9,7 +10,6 @@ interface AvatarProps {
name?: string | null;
size?: number;
className?: string;
- imageClassName?: string;
fallbackClassName?: string;
}
@@ -22,7 +22,6 @@ export function Avatar({
name,
size = 40,
className,
- imageClassName,
fallbackClassName,
}: AvatarProps) {
const [imageError, setImageError] = React.useState(false);
@@ -78,8 +77,8 @@ export function Avatar({
) : (
<Image
source={imageUrl}
- className={cn("h-full w-full", imageClassName)}
- style={{ resizeMode: "cover" }}
+ style={{ width: "100%", height: "100%" }}
+ contentFit="cover"
onError={() => setImageError(true)}
/>
)}
diff --git a/apps/mobile/lib/hooks.ts b/apps/mobile/lib/hooks.ts
index 3540df23..c3cb9d22 100644
--- a/apps/mobile/lib/hooks.ts
+++ b/apps/mobile/lib/hooks.ts
@@ -1,10 +1,14 @@
-import { ImageURISource } from "react-native";
import { useQuery } from "@tanstack/react-query";
import useAppSettings from "./settings";
import { buildApiHeaders } from "./utils";
-export function useAssetUrl(assetId: string): ImageURISource {
+interface AssetSource {
+ uri: string;
+ headers: Record<string, string>;
+}
+
+export function useAssetUrl(assetId: string): AssetSource {
const { settings } = useAppSettings();
return {
uri: `${settings.address}/api/assets/${assetId}`,