Skip to content

Commit

Permalink
# Allow option for viewing custom menu links
Browse files Browse the repository at this point in the history
- Added new 'Other' setting to toggle new tab visibility
- Added new Tab to show custom links
- Added icon asset for list
  • Loading branch information
herrrta committed Nov 29, 2024
1 parent 5292d89 commit 3797a2a
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 1 deletion.
20 changes: 20 additions & 0 deletions app/(auth)/(tabs)/(custom-links)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {Stack} from "expo-router";
import { Platform } from "react-native";

export default function CustomMenuLayout() {
return (
<Stack>
<Stack.Screen
name="index"
options={{
headerShown: true,
headerLargeTitle: true,
headerTitle: "Custom Links",
headerBlurEffect: "prominent",
headerTransparent: Platform.OS === "ios",
headerShadowVisible: false,
}}
/>
</Stack>
);
}
73 changes: 73 additions & 0 deletions app/(auth)/(tabs)/(custom-links)/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {FlatList, TouchableOpacity, View} from "react-native";
import {useSafeAreaInsets} from "react-native-safe-area-context";
import React, {useCallback, useEffect, useState} from "react";
import {useAtom} from "jotai/index";
import {apiAtom} from "@/providers/JellyfinProvider";
import {ListItem} from "@/components/ListItem";
import * as WebBrowser from 'expo-web-browser';
import Ionicons from '@expo/vector-icons/Ionicons';
import {Text} from "@/components/common/Text";

export interface MenuLink {
name: string,
url: string,
icon: string
}

export default function menuLinks() {
const [api] = useAtom(apiAtom);
const insets = useSafeAreaInsets()
const [menuLinks, setMenuLinks] = useState<MenuLink[]>([])

const getMenuLinks = useCallback(async () => {
try {
const response = await api?.axiosInstance.get(api?.basePath + "/web/config.json")
const config = response?.data;

if (!config && !config.hasOwnProperty("menuLinks")) {
console.error("Menu links not found");
return;
}

setMenuLinks(config?.menuLinks as MenuLink[])
} catch (error) {
console.error("Failed to retrieve config:", error);
}
},
[api]
)

useEffect(() => { getMenuLinks() }, []);
return (
<FlatList
contentInsetAdjustmentBehavior="automatic"
contentContainerStyle={{
paddingTop: 10,
paddingLeft: insets.left,
paddingRight: insets.right,
}}
data={menuLinks}
renderItem={({item}) => (
<TouchableOpacity onPress={() => WebBrowser.openBrowserAsync(item.url) }>
<ListItem
title={item.name}
iconAfter={<Ionicons name="link" size={24} color="white"/>}
/>
</TouchableOpacity>
)
}
ItemSeparatorComponent={() => (
<View
style={{
width: 10,
height: 10,
}}/>
)}
ListEmptyComponent={
<View className="flex flex-col items-center justify-center h-full">
<Text className="font-bold text-xl text-neutral-500">No links</Text>
</View>
}
/>
);
}
13 changes: 13 additions & 0 deletions app/(auth)/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type {
TabNavigationState,
} from "@react-navigation/native";
import { SystemBars } from "react-native-edge-to-edge";
import {useSettings} from "@/utils/atoms/settings";

export const NativeTabs = withLayoutContext<
BottomTabNavigationOptions,
Expand All @@ -27,6 +28,7 @@ export const NativeTabs = withLayoutContext<
>(Navigator);

export default function TabLayout() {
const [settings] = useSettings();
return (
<>
<SystemBars hidden={false} style="light" />
Expand Down Expand Up @@ -71,6 +73,17 @@ export default function TabLayout() {
: () => ({ sfSymbol: "rectangle.stack" }),
}}
/>
<NativeTabs.Screen
name="(custom-links)"
options={{
title: "Custom Links",
tabBarIcon: Platform.OS == "android"
? () => require("@/assets/icons/list.png")
: () => ({sfSymbol: "list.dash"}),
tabBarButton: (p) =>
settings?.showCustomMenuLinks == true ? undefined : null,
}}
/>
</NativeTabs>
</>
);
Expand Down
Binary file added assets/icons/list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions components/settings/SettingToggles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,26 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
</View>
)}
</View>

<View className="flex flex-row items-center justify-between bg-neutral-900 p-4">
<View className="shrink">
<Text className="font-semibold">Show Custom Menu Links</Text>
<Text className="text-xs opacity-50">
Show custom menu links defined inside your Jellyfin web config.json file
</Text>
<TouchableOpacity
onPress={() =>
Linking.openURL("https://jellyfin.org/docs/general/clients/web-config/#custom-menu-links")
}
>
<Text className="text-xs text-purple-600">More info</Text>
</TouchableOpacity>
</View>
<Switch
value={settings.showCustomMenuLinks}
onValueChange={(value) => updateSettings({ showCustomMenuLinks: value })}
/>
</View>
</View>
</View>

Expand Down
4 changes: 3 additions & 1 deletion utils/atoms/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ export type Settings = {
rewindSkipTime: number;
optimizedVersionsServerUrl?: string | null;
downloadMethod: "optimized" | "remux";
autoDownload: boolean;
autoDownload: boolean,
showCustomMenuLinks: boolean;
};

const loadSettings = (): Settings => {
Expand Down Expand Up @@ -103,6 +104,7 @@ const loadSettings = (): Settings => {
optimizedVersionsServerUrl: null,
downloadMethod: "remux",
autoDownload: false,
showCustomMenuLinks: false,
};

try {
Expand Down

0 comments on commit 3797a2a

Please sign in to comment.