mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-10-15 22:55:42 -04:00
fix(tracking): report when a title was already in the library
updateStatus now returns { alreadyAdded }. Native toasts say so instead of
claiming success, and the Explore hero hides Add to Watchlist for library titles.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
19 files changed
+155
-6
No files matched your search
@@ -70,7 +70,9 @@ export default function ExploreScreen() {
|
||||
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}
|
||||
>
|
||||
<View className="gap-8">
|
||||
{heroItem && <HeroBanner item={heroItem} />}
|
||||
{heroItem && (
|
||||
<HeroBanner item={{ ...heroItem, userStatus: trendingStatuses[heroItem.id] ?? null }} />
|
||||
)}
|
||||
|
||||
<Animated.View entering={FadeInDown.duration(300).delay(100)}>
|
||||
<FilterableTitleRow
|
||||
|
||||
@@ -21,6 +21,7 @@ export interface HeroBannerItem {
|
||||
overview?: string | null;
|
||||
voteAverage?: number | null;
|
||||
releaseDate?: string | null;
|
||||
userStatus?: string | null;
|
||||
}
|
||||
|
||||
export function HeroBanner({ item }: { item: HeroBannerItem }) {
|
||||
@@ -127,6 +128,7 @@ export function HeroBanner({ item }: { item: HeroBannerItem }) {
|
||||
</Pressable>
|
||||
</Link.Trigger>
|
||||
<Link.Preview />
|
||||
{!item.userStatus && (
|
||||
<Link.Menu>
|
||||
<Link.MenuAction
|
||||
title={t`Add to Watchlist`}
|
||||
@@ -134,6 +136,7 @@ export function HeroBanner({ item }: { item: HeroBannerItem }) {
|
||||
onPress={() => titleActions.addToWatchlist(item.id, item.title)}
|
||||
/>
|
||||
</Link.Menu>
|
||||
)}
|
||||
</Link>
|
||||
</Animated.View>
|
||||
</GestureDetector>
|
||||
|
||||
@@ -44,7 +44,11 @@ export function useTitleActions(options?: UseTitleActionsOptions) {
|
||||
|
||||
const updateStatus = useMutation(
|
||||
orpc.tracking.updateStatus.mutationOptions({
|
||||
onSuccess: (_data, input) => {
|
||||
onSuccess: (data, input) => {
|
||||
if (input.status === "watchlist" && data?.alreadyAdded) {
|
||||
toast.info(t`Already in your library`);
|
||||
return invalidateTitleQueries();
|
||||
}
|
||||
const statusMessages: Record<string, string> = {
|
||||
watchlist: t`Added to watchlist`,
|
||||
};
|
||||
|
||||
@@ -41,12 +41,20 @@ export function invalidateTitleQueries(): Promise<unknown> {
|
||||
export const titleActions = {
|
||||
async addToWatchlist(id: string, titleName?: string) {
|
||||
try {
|
||||
await client.tracking.updateStatus({ id, status: "watchlist" });
|
||||
const result = await client.tracking.updateStatus({ id, status: "watchlist" });
|
||||
if (result.alreadyAdded) {
|
||||
toast.info(
|
||||
titleName
|
||||
? i18n._(msg`"${titleName}" is already in your library`)
|
||||
: i18n._(msg`Already in your library`),
|
||||
);
|
||||
} else {
|
||||
toast.success(
|
||||
titleName
|
||||
? i18n._(msg`Added "${titleName}" to watchlist`)
|
||||
: i18n._(msg`Added to watchlist`),
|
||||
);
|
||||
}
|
||||
invalidateTitleQueries();
|
||||
} catch {
|
||||
toast.error(i18n._(msg`Failed to add to watchlist`));
|
||||
|
||||
@@ -90,7 +90,7 @@ export const updateStatus = os.tracking.updateStatus
|
||||
.handler(async ({ input, context }) => {
|
||||
if (input.status === null) {
|
||||
removeTitleStatus(context.user.id, input.id);
|
||||
return;
|
||||
return { alreadyAdded: false };
|
||||
}
|
||||
|
||||
// Auto-import from TMDB if the title is a shell (absorbs quickAdd logic)
|
||||
@@ -106,6 +106,8 @@ export const updateStatus = os.tracking.updateStatus
|
||||
log.warn(`Failed to import ${result.type} TMDB ${result.tmdbId}:`, err);
|
||||
});
|
||||
}
|
||||
|
||||
return { alreadyAdded: result.alreadyAdded };
|
||||
});
|
||||
|
||||
export const rate = os.tracking.rate.use(authed).handler(({ input, context }) => {
|
||||
|
||||
@@ -1983,7 +1983,23 @@
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"alreadyAdded": {
|
||||
"type": "boolean",
|
||||
"description": "True when the title was already in the library, so nothing changed"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"alreadyAdded"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "404",
|
||||
|
||||
@@ -146,7 +146,13 @@ export const contract = {
|
||||
"Set the user's tracking status for a title. Use null to remove the title from the library entirely.",
|
||||
})
|
||||
.input(UpdateStatusInput)
|
||||
.output(z.void())
|
||||
.output(
|
||||
z.object({
|
||||
alreadyAdded: z
|
||||
.boolean()
|
||||
.describe("True when the title was already in the library, so nothing changed"),
|
||||
}),
|
||||
)
|
||||
.errors({
|
||||
NOT_FOUND: {
|
||||
message: "Title not found",
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...و{remainingErrors} أخرى"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr "هل لديك حساب بالفعل؟"
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr "هل لديك حساب بالفعل؟ تسجيل الدخول"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "متاح أيضاً على"
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...und {remainingErrors} weitere"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr "Bereits ein Konto?"
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr "Bereits ein Konto? Anmelden"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "Auch verfügbar auf"
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...and {remainingErrors} more"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr "\"{titleName}\" is already in your library"
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr ""
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr ""
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr "Already in your library"
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "Also available on"
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...y {remainingErrors} más"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr "¿Ya tienes una cuenta?"
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr "¿Ya tienes una cuenta? Inicia sesión"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "También disponible en"
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...et {remainingErrors} de plus"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr "Vous avez déjà un compte ?"
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr "Vous avez déjà un compte ? Se connecter"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "Aussi disponible sur"
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...ועוד {remainingErrors}"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr "כבר יש לך חשבון?"
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr "כבר יש לך חשבון? התחבר"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "זמין גם ב"
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...e altri {remainingErrors}"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr "Hai già un account?"
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr "Hai già un account? Accedi"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "Disponibile anche su"
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...他{remainingErrors}件"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr "すでにアカウントをお持ちですか?"
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr "すでにアカウントをお持ちの方はサインイン"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "他でも視聴可能"
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...그 외 {remainingErrors}개 더"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr "이미 계정이 있으신가요?"
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr "이미 계정이 있으신가요? 로그인"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "다음에서도 이용 가능"
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...en {remainingErrors} meer"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr "Al een account?"
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr "Al een account? Aanmelden"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "Ook beschikbaar op"
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...e mais {remainingErrors}"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr "Já tem uma conta?"
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr "Já tem uma conta? Entrar"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "Também disponível em"
|
||||
|
||||
@@ -26,6 +26,10 @@ msgstr ""
|
||||
msgid "...and {remainingErrors} more"
|
||||
msgstr "...及另外 {remainingErrors} 个"
|
||||
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "\"{titleName}\" is already in your library"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: systemHealth.data.imageCache.imageCount
|
||||
#: apps/native/src/app/(tabs)/(settings)/index.tsx
|
||||
msgid "{0, plural, one {# image} other {# images}}"
|
||||
@@ -407,6 +411,11 @@ msgstr "已有账户?"
|
||||
msgid "Already have an account? Sign in"
|
||||
msgstr "已有账户?立即登录"
|
||||
|
||||
#: apps/native/src/hooks/use-title-actions.ts
|
||||
#: apps/native/src/lib/title-actions.ts
|
||||
msgid "Already in your library"
|
||||
msgstr ""
|
||||
|
||||
#: apps/web/src/components/titles/title-availability.tsx
|
||||
msgid "Also available on"
|
||||
msgstr "同样在以下平台可用"
|
||||
|
||||
Reference in new issue
Block a user