mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-05-30 18:48:30 +01:00
fix: restore nested dropdown sections for expo 55 on iOS using nested ContextMenus
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Button, ContextMenu, Host, Picker } from "@expo/ui/swift-ui";
|
||||
import { Button, ContextMenu, Host } from "@expo/ui/swift-ui";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { BottomSheetScrollView } from "@gorhom/bottom-sheet";
|
||||
import React, { useEffect } from "react";
|
||||
@@ -254,23 +254,39 @@ const PlatformDropdownComponent = ({
|
||||
// Otherwise render as individual buttons
|
||||
if (radioOptions.length > 0) {
|
||||
if (group.title) {
|
||||
// Use Picker for grouped options
|
||||
// Use a nested ContextMenu as a submenu for grouped options
|
||||
const selectedOption = radioOptions.find(
|
||||
(opt) => opt.selected,
|
||||
);
|
||||
const displayTitle = selectedOption
|
||||
? `${group.title}: ${selectedOption.label}`
|
||||
: group.title;
|
||||
|
||||
items.push(
|
||||
<Picker
|
||||
key={`picker-${groupIndex}`}
|
||||
label={group.title}
|
||||
options={radioOptions.map((opt) => opt.label)}
|
||||
variant='menu'
|
||||
selectedIndex={radioOptions.findIndex(
|
||||
(opt) => opt.selected,
|
||||
)}
|
||||
onOptionSelected={(event: any) => {
|
||||
const index = event.nativeEvent.index;
|
||||
const selectedOption = radioOptions[index];
|
||||
selectedOption?.onPress();
|
||||
onOptionSelect?.(selectedOption?.value);
|
||||
}}
|
||||
/>,
|
||||
<ContextMenu key={`submenu-${groupIndex}`}>
|
||||
<ContextMenu.Trigger>
|
||||
<Button>{displayTitle}</Button>
|
||||
</ContextMenu.Trigger>
|
||||
<ContextMenu.Items>
|
||||
{radioOptions.map((option, optionIndex) => (
|
||||
<Button
|
||||
key={`radio-${groupIndex}-${optionIndex}`}
|
||||
systemImage={
|
||||
option.selected
|
||||
? "checkmark.circle.fill"
|
||||
: "circle"
|
||||
}
|
||||
onPress={() => {
|
||||
option.onPress();
|
||||
onOptionSelect?.(option.value);
|
||||
}}
|
||||
disabled={option.disabled}
|
||||
>
|
||||
{option.label}
|
||||
</Button>
|
||||
))}
|
||||
</ContextMenu.Items>
|
||||
</ContextMenu>,
|
||||
);
|
||||
} else {
|
||||
// Render radio options as direct buttons
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, ContextMenu, Host, Picker } from "@expo/ui/swift-ui";
|
||||
import { Button, ContextMenu, Host } from "@expo/ui/swift-ui";
|
||||
import { Platform, View } from "react-native";
|
||||
import { FilterButton } from "@/components/filters/FilterButton";
|
||||
import { JellyseerrSearchSort } from "@/components/jellyseerr/JellyseerrIndexPage";
|
||||
@@ -49,32 +49,66 @@ export const DiscoverFilters: React.FC<DiscoverFiltersProps> = ({
|
||||
></Button>
|
||||
</ContextMenu.Trigger>
|
||||
<ContextMenu.Items>
|
||||
<Picker
|
||||
label={t("library.filters.sort_by")}
|
||||
options={sortOptions.map((item) =>
|
||||
t(`home.settings.plugins.jellyseerr.order_by.${item}`),
|
||||
)}
|
||||
variant='menu'
|
||||
selectedIndex={sortOptions.indexOf(
|
||||
jellyseerrOrderBy as unknown as string,
|
||||
)}
|
||||
onOptionSelected={(event: any) => {
|
||||
const index = event.nativeEvent.index;
|
||||
setJellyseerrOrderBy(
|
||||
sortOptions[index] as unknown as JellyseerrSearchSort,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Picker
|
||||
label={t("library.filters.sort_order")}
|
||||
options={orderOptions.map((item) => t(`library.filters.${item}`))}
|
||||
variant='menu'
|
||||
selectedIndex={orderOptions.indexOf(jellyseerrSortOrder)}
|
||||
onOptionSelected={(event: any) => {
|
||||
const index = event.nativeEvent.index;
|
||||
setJellyseerrSortOrder(orderOptions[index]);
|
||||
}}
|
||||
/>
|
||||
<ContextMenu>
|
||||
<ContextMenu.Trigger>
|
||||
<Button>
|
||||
{`${t("library.filters.sort_by")}: ${t(
|
||||
`home.settings.plugins.jellyseerr.order_by.${jellyseerrOrderBy}`,
|
||||
)}`}
|
||||
</Button>
|
||||
</ContextMenu.Trigger>
|
||||
<ContextMenu.Items>
|
||||
{sortOptions.map((item) => {
|
||||
const label = t(
|
||||
`home.settings.plugins.jellyseerr.order_by.${item}`,
|
||||
);
|
||||
const isSelected =
|
||||
jellyseerrOrderBy ===
|
||||
(item as unknown as JellyseerrSearchSort);
|
||||
return (
|
||||
<Button
|
||||
key={item}
|
||||
systemImage={
|
||||
isSelected ? "checkmark.circle.fill" : "circle"
|
||||
}
|
||||
onPress={() =>
|
||||
setJellyseerrOrderBy(
|
||||
item as unknown as JellyseerrSearchSort,
|
||||
)
|
||||
}
|
||||
>
|
||||
{label}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</ContextMenu.Items>
|
||||
</ContextMenu>
|
||||
<ContextMenu>
|
||||
<ContextMenu.Trigger>
|
||||
<Button>
|
||||
{`${t("library.filters.sort_order")}: ${t(
|
||||
`library.filters.${jellyseerrSortOrder}`,
|
||||
)}`}
|
||||
</Button>
|
||||
</ContextMenu.Trigger>
|
||||
<ContextMenu.Items>
|
||||
{orderOptions.map((item) => {
|
||||
const label = t(`library.filters.${item}`);
|
||||
const isSelected = jellyseerrSortOrder === item;
|
||||
return (
|
||||
<Button
|
||||
key={item}
|
||||
systemImage={
|
||||
isSelected ? "checkmark.circle.fill" : "circle"
|
||||
}
|
||||
onPress={() => setJellyseerrSortOrder(item)}
|
||||
>
|
||||
{label}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</ContextMenu.Items>
|
||||
</ContextMenu>
|
||||
</ContextMenu.Items>
|
||||
</ContextMenu>
|
||||
</Host>
|
||||
|
||||
Reference in New Issue
Block a user