mirror of
https://github.com/linkwarden/linkwarden.git
synced 2026-03-03 03:47:02 +00:00
mobile: bug fix + code cleanup
This commit is contained in:
@@ -1,13 +1,11 @@
|
||||
import { Platform, ScrollView, StyleSheet } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { useDashboardData } from "@linkwarden/router/dashboardData";
|
||||
import useAuthStore from "@/store/auth";
|
||||
import { DashboardSection as PrismaDashboardSection } from "@linkwarden/prisma/client";
|
||||
import { DashboardSection as DashboardSectionType } from "@linkwarden/prisma/client";
|
||||
import { useUser } from "@linkwarden/router/user";
|
||||
import { useCollections } from "@linkwarden/router/collections";
|
||||
import { useTags } from "@linkwarden/router/tags";
|
||||
import { useRouter } from "expo-router";
|
||||
import { rawTheme, ThemeName } from "@/lib/colors";
|
||||
import { useColorScheme } from "nativewind";
|
||||
import Spinner from "@/components/ui/Spinner";
|
||||
@@ -27,10 +25,8 @@ export default function DashboardScreen() {
|
||||
|
||||
const { colorScheme } = useColorScheme();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const [dashboardSections, setDashboardSections] = useState<
|
||||
PrismaDashboardSection[]
|
||||
DashboardSectionType[]
|
||||
>(user?.dashboardSections || []);
|
||||
|
||||
const [numberOfLinks, setNumberOfLinks] = useState(0);
|
||||
|
||||
@@ -22,7 +22,7 @@ import LinkListing from "@/components/LinkListing";
|
||||
import { useColorScheme } from "nativewind";
|
||||
import { useRouter } from "expo-router";
|
||||
|
||||
// Don't remove this, spent a couple of days to figure out why the app crashes in production :|
|
||||
// Don't use prisma client's DashboardSectionType, it'll crash in production (React Native)
|
||||
type DashboardSectionType =
|
||||
| "STATS"
|
||||
| "RECENT_LINKS"
|
||||
|
||||
@@ -29,6 +29,7 @@ import { rawTheme, ThemeName } from "@/lib/colors";
|
||||
import { useColorScheme } from "nativewind";
|
||||
import { CalendarDays, Folder } from "lucide-react-native";
|
||||
import useDataStore from "@/store/data";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
type Props = {
|
||||
link: LinkIncludingShortenedCollectionAndTags;
|
||||
@@ -45,15 +46,17 @@ const LinkListing = ({ link, dashboard }: Props) => {
|
||||
|
||||
const deleteLink = useDeleteLink(auth);
|
||||
|
||||
let shortendURL;
|
||||
const [url, setUrl] = useState("");
|
||||
|
||||
try {
|
||||
if (link.url) {
|
||||
shortendURL = new URL(link.url).host.toLowerCase();
|
||||
useEffect(() => {
|
||||
try {
|
||||
if (link.url) {
|
||||
setUrl(new URL(link.url).host.toLowerCase());
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}, [link]);
|
||||
|
||||
return (
|
||||
<ContextMenu.Root>
|
||||
@@ -106,12 +109,12 @@ const LinkListing = ({ link, dashboard }: Props) => {
|
||||
{decode(link.name || link.description || link.url)}
|
||||
</Text>
|
||||
|
||||
{shortendURL && (
|
||||
{url && (
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
className="mt-1.5 font-light text-sm text-base-content"
|
||||
>
|
||||
{shortendURL}
|
||||
{url}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
@@ -176,7 +179,7 @@ const LinkListing = ({ link, dashboard }: Props) => {
|
||||
<ContextMenu.Item
|
||||
key="open-original"
|
||||
onSelect={() => {
|
||||
if (user && link) {
|
||||
if (link) {
|
||||
const format = getOriginalFormat(link);
|
||||
|
||||
data.preferredBrowser === "app"
|
||||
|
||||
@@ -85,16 +85,6 @@ export function Card({ link, editMode, dashboardType }: Props) {
|
||||
|
||||
const { refetch } = useGetLink({ id: link.id as number, isPublicRoute });
|
||||
|
||||
let shortendURL;
|
||||
|
||||
try {
|
||||
if (link.url) {
|
||||
shortendURL = new URL(link.url).host.toLowerCase();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
const [collection, setCollection] =
|
||||
useState<CollectionIncludingMembersAndLinkCount>(
|
||||
collections.find(
|
||||
|
||||
@@ -102,16 +102,6 @@ export default function LinkCard({ link, columns, editMode }: Props) {
|
||||
}
|
||||
};
|
||||
|
||||
let shortendURL;
|
||||
|
||||
try {
|
||||
if (link.url) {
|
||||
shortendURL = new URL(link.url).host.toLowerCase();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
const [collection, setCollection] =
|
||||
useState<CollectionIncludingMembersAndLinkCount>(
|
||||
collections.find(
|
||||
|
||||
@@ -104,16 +104,6 @@ export default function LinkMasonry({ link, editMode, columns }: Props) {
|
||||
}
|
||||
};
|
||||
|
||||
let shortendURL;
|
||||
|
||||
try {
|
||||
if (link.url) {
|
||||
shortendURL = new URL(link.url).host.toLowerCase();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
const [collection, setCollection] =
|
||||
useState<CollectionIncludingMembersAndLinkCount>(
|
||||
collections.find(
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
import { LinkIncludingShortenedCollectionAndTags } from "@linkwarden/types";
|
||||
import Link from "next/link";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export default function LinkTypeBadge({
|
||||
link,
|
||||
}: {
|
||||
link: LinkIncludingShortenedCollectionAndTags;
|
||||
}) {
|
||||
let shortendURL;
|
||||
const [url, setUrl] = useState("");
|
||||
|
||||
if (link.type === "url" && link.url) {
|
||||
try {
|
||||
shortendURL = new URL(link.url).host.toLowerCase();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
useEffect(() => {
|
||||
if (link.type === "url" && link.url) {
|
||||
try {
|
||||
setUrl(new URL(link.url).host.toLowerCase());
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [link]);
|
||||
|
||||
const typeIcon = () => {
|
||||
switch (link.type) {
|
||||
@@ -27,7 +30,7 @@ export default function LinkTypeBadge({
|
||||
}
|
||||
};
|
||||
|
||||
return link.url && shortendURL ? (
|
||||
return link.url && url ? (
|
||||
<Link
|
||||
href={link.url || ""}
|
||||
target="_blank"
|
||||
@@ -38,7 +41,7 @@ export default function LinkTypeBadge({
|
||||
className="flex gap-1 item-center select-none text-neutral hover:opacity-70 duration-100 max-w-full w-fit"
|
||||
>
|
||||
<i className="bi-link-45deg text-lg leading-none"></i>
|
||||
<p className="text-xs truncate">{shortendURL}</p>
|
||||
<p className="text-xs truncate">{url}</p>
|
||||
</Link>
|
||||
) : (
|
||||
<div className="flex gap-1 item-center select-none text-neutral duration-100 max-w-full w-fit">
|
||||
|
||||
@@ -2,8 +2,15 @@ import {
|
||||
ArchivedFormat,
|
||||
LinkIncludingShortenedCollectionAndTags,
|
||||
} from "@linkwarden/types";
|
||||
import { LinksRouteTo } from "@linkwarden/prisma/client";
|
||||
import { formatAvailable } from "@linkwarden/lib/formatStats";
|
||||
|
||||
// Don't use prisma client's LinksRouteTo, it'll crash in production (React Native)
|
||||
type LinksRouteTo =
|
||||
| "ORIGINAL"
|
||||
| "PDF"
|
||||
| "READABLE"
|
||||
| "MONOLITH"
|
||||
| "SCREENSHOT"
|
||||
| "DETAILS";
|
||||
|
||||
const getFormatBasedOnPreference = ({
|
||||
link,
|
||||
@@ -15,24 +22,24 @@ const getFormatBasedOnPreference = ({
|
||||
// Return the format based on the account's preference
|
||||
// If the user's preference is not available, return null (original url)
|
||||
|
||||
if (preference === LinksRouteTo.ORIGINAL && link.type === "url") {
|
||||
if (preference === "ORIGINAL" && link.type === "url") {
|
||||
return null;
|
||||
} else if (preference === LinksRouteTo.PDF || link.type === "pdf") {
|
||||
if (!formatAvailable(link, "pdf")) return null;
|
||||
} else if (preference === "PDF" || link.type === "pdf") {
|
||||
if (!link.pdf || link.pdf === "unavailable") return null;
|
||||
|
||||
return ArchivedFormat.pdf;
|
||||
} else if (preference === LinksRouteTo.READABLE && link.type === "url") {
|
||||
if (!formatAvailable(link, "readable")) return null;
|
||||
} else if (preference === "READABLE" && link.type === "url") {
|
||||
if (!link.readable || link.readable === "unavailable") return null;
|
||||
|
||||
return ArchivedFormat.readability;
|
||||
} else if (preference === LinksRouteTo.SCREENSHOT || link.type === "image") {
|
||||
if (!formatAvailable(link, "image")) return null;
|
||||
} else if (preference === "SCREENSHOT" || link.type === "image") {
|
||||
if (!link.image || link.image === "unavailable") return null;
|
||||
|
||||
return link?.image?.endsWith("png")
|
||||
? ArchivedFormat.png
|
||||
: ArchivedFormat.jpeg;
|
||||
} else if (preference === LinksRouteTo.MONOLITH) {
|
||||
if (!formatAvailable(link, "monolith")) return null;
|
||||
} else if (preference === "MONOLITH") {
|
||||
if (!link.monolith || link.monolith === "unavailable") return null;
|
||||
|
||||
return ArchivedFormat.monolith;
|
||||
} else {
|
||||
|
||||
@@ -5,9 +5,8 @@ import {
|
||||
|
||||
const getOriginalFormat = (
|
||||
link: LinkIncludingShortenedCollectionAndTags
|
||||
): ArchivedFormat | string | null => {
|
||||
if (link.url && link.type === "url") return link.url;
|
||||
else if (link.type === "pdf") return ArchivedFormat.pdf;
|
||||
): ArchivedFormat | null => {
|
||||
if (link.type === "pdf") return ArchivedFormat.pdf;
|
||||
else if (link.type === "image")
|
||||
return link.image?.endsWith("png")
|
||||
? ArchivedFormat.png
|
||||
|
||||
Reference in New Issue
Block a user