Merge branch '59-improve-onboarding-experience' of github.com:anultravioletaurora/Jellify into 59-improve-onboarding-experience

This commit is contained in:
Violet Caulfield
2025-02-16 09:05:34 -06:00
25 changed files with 27 additions and 144 deletions
+4 -4
View File
@@ -72,15 +72,15 @@ Playlist
<img src="screenshots/search.png" alt="Search" width="275" height="600">
### Player
<img src="screenshots/player.png" alt="Player">
<img src="screenshots/player.png" alt="Player" width="275" height="600">
<img src="screenshots/player_queue.png" alt="Queue">
<img src="screenshots/player_queue.png" alt="Queue" width="275" height="600">
### CarPlay (Sneak Preview)
<img src="screenshots/carplay_nowplaying.jpeg" alt="Now Playing (CarPlay)">
<img src="screenshots/carplay_nowplaying.jpeg" alt="Now Playing (CarPlay)" width="500" height="350">
### On the Server
<img src="https://github.com/user-attachments/assets/741884a2-b9b7-4081-b3a0-6655d08071dc" alt="Playback Tracking">
<img src="https://github.com/user-attachments/assets/741884a2-b9b7-4081-b3a0-6655d08071dc" alt="Playback Tracking" width="300" height="200">
## 🏗 Built with:
### 🎨 Frontend
-3
View File
@@ -135,9 +135,6 @@ export function AlbumScreen({
</YStack>
)}
// style={{
// overflow: 'hidden' // Prevent unnecessary memory usage
// }}
/>
)
}
-3
View File
@@ -39,9 +39,6 @@ export default function Albums({ navigation }: AlbumsProps) : React.JSX.Element
/>
)
}}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
)
}
-3
View File
@@ -97,9 +97,6 @@ export default function Artist({
/>
)
}}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
</ScrollView>
)
-3
View File
@@ -55,9 +55,6 @@ export default function Artists({
/>
)
}}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
)
}
@@ -32,9 +32,7 @@ export default function BlurhashedImage({
Math.ceil(height ?? width / 100) * 100 // So these keys need to match
],
queryFn: () => fetchItemImage(item.AlbumId ? item.AlbumId : item.Id!, type ?? ImageType.Primary, width, height ?? width),
staleTime: (1000 * 60 * 60) * 24, // 1 day, images probably don't refresh that often
gcTime: (1000 * 1 * 1) * 1 // 1 second, these are stored on disk anyways so refetching is cheap
});;
});
const blurhash = !isEmpty(item.ImageBlurHashes)
&& !isEmpty(type ? item.ImageBlurHashes[type] : item.ImageBlurHashes.Primary)
@@ -52,9 +52,6 @@ export default function HorizontalCardList({
/>
) : undefined}
}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
)
}
+1 -1
View File
@@ -27,7 +27,7 @@ export default function IconCard({
>
<Card
animation="bouncy"
borderRadius={circular ? 300 : 25}
borderRadius={circular ? 300 : 2}
hoverStyle={{ scale: 0.925 }}
pressStyle={{ scale: 0.875 }}
width={width ? width : 150}
-3
View File
@@ -36,9 +36,6 @@ export default function Playlists({ navigation }: { navigation: NativeStackNavig
}} />
)
}}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
</View>
)
-29
View File
@@ -1,29 +0,0 @@
import Item from "../../../components/Global/components/item";
import { StackParamList } from "../../../components/types"
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import { NativeStackNavigationProp } from "@react-navigation/native-stack"
import { FlatList } from "react-native"
interface UserPlaylistsProps {
playlists: BaseItemDto[];
navigation: NativeStackNavigationProp<StackParamList, 'UserPlaylists'>;
}
export default function RecentArtistsScreen({
playlists,
navigation
}: UserPlaylistsProps) : React.JSX.Element {
return (
<FlatList
data={playlists}
renderItem={({ index, item: artist }) => {
return <Item item={artist} queueName="" navigation={navigation} />
}}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
)
}
@@ -1,29 +0,0 @@
import Item from "../../../components/Global/components/item";
import { StackParamList } from "../../../components/types"
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import { NativeStackNavigationProp } from "@react-navigation/native-stack"
import { FlatList } from "react-native"
interface RecentArtistsProps {
artists: BaseItemDto[];
navigation: NativeStackNavigationProp<StackParamList, 'RecentArtists'>;
}
export default function RecentArtistsScreen({
artists,
navigation
}: RecentArtistsProps) : React.JSX.Element {
return (
<FlatList
data={artists}
renderItem={({ index, item: artist }) => {
return <Item item={artist} queueName="" navigation={navigation} />
}}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
)
}
@@ -1,29 +0,0 @@
import Item from "../../../components/Global/components/item";
import { StackParamList } from "../../../components/types"
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import { NativeStackNavigationProp } from "@react-navigation/native-stack"
import { FlatList } from "react-native"
interface RecentlyPlayedProps {
tracks: BaseItemDto[];
navigation: NativeStackNavigationProp<StackParamList, 'RecentTracks'>;
}
export default function RecentArtistsScreen({
tracks,
navigation
}: RecentlyPlayedProps) : React.JSX.Element {
return (
<FlatList
data={tracks}
renderItem={({ index, item: track }) => {
return <Item item={track} queueName="Recently Played" navigation={navigation} />
}}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
)
}
-3
View File
@@ -35,9 +35,6 @@ export default function Library({
/>
)
}}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
</SafeAreaView>
)
+2 -2
View File
@@ -75,8 +75,8 @@ export default function ServerLibrary(): React.JSX.Element {
musicLibraryId: libraryId!,
musicLibraryName: libraries?.filter((library) => library.Id == libraryId)[0].Name ?? "No library name",
musicLibraryPrimaryImageId: libraries?.filter((library) => library.Id == libraryId)[0].ImageTags!.Primary,
playlistLibraryId: playlistLibrary!.Id!,
playlistLibraryPrimaryImageId: playlistLibrary!.ImageTags!.Primary,
playlistLibraryId: playlistLibrary?.Id!,
playlistLibraryPrimaryImageId: playlistLibrary?.ImageTags!.Primary,
});
setLoggedIn(true);
}}>
+2 -1
View File
@@ -153,6 +153,7 @@ export default function Playlist({
return (
<DraggableFlatList
removeClippedSubviews={false}
contentInsetAdjustmentBehavior="automatic"
data={playlistTracks}
dragHitSlop={{ left: -50 }} // https://github.com/computerjazz/react-native-draggable-flatlist/issues/336
@@ -213,7 +214,7 @@ export default function Playlist({
color={"$borderColor"}
style={{ display: "block"}}
>
Total Runtime:
Total Runtime:
</Text>
<RunTimeTicks>{ playlist.RunTimeTicks }</RunTimeTicks>
</XStack>
-3
View File
@@ -51,9 +51,6 @@ export default function FavoritePlaylists({ navigation }: FavoritePlaylistsProps
/>
)
}}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
)
}
-3
View File
@@ -64,9 +64,6 @@ export default function Search({
<Item item={item} queueName={searchString ?? "Search"} navigation={navigation} />
)
}}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
)
}
-3
View File
@@ -41,9 +41,6 @@ export default function TracksScreen({
)
}}
style={{
overflow: 'hidden' // Prevent unnecessary memory usage
}}
/>
)
}
+2 -1
View File
@@ -3,8 +3,9 @@ import { QueryClient } from "@tanstack/react-query";
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
gcTime: (1000 * 60 * 60 * 24) * 5, // 5 days, for maximum cache-age
staleTime: (1000 * 60 * 30), // 30 minutes, this can be refreshed manually anyways
staleTime: (1000 * 60 * 60 * 1), // 1 hour, this can be refreshed manually anyways
}
}
});
+1 -1
View File
@@ -8,6 +8,6 @@ ruby ">=3.0.0"
# Exclude problematic versions of cocoapods and activesupport that causes build failures.
gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
gem 'xcodeproj', '< 1.26.0'
gem 'xcodeproj', '< 1.27.1'
gem 'concurrent-ruby', '< 1.3.4'
gem "fastlane"
+4 -4
View File
@@ -230,7 +230,7 @@ GEM
molinillo (0.8.0)
multi_json (1.15.0)
multipart-post (2.4.1)
nanaimo (0.3.0)
nanaimo (0.4.0)
nap (1.1.0)
naturally (2.2.1)
netrc (0.11.0)
@@ -276,12 +276,12 @@ GEM
uber (0.1.0)
unicode-display_width (2.6.0)
word_wrap (1.0.0)
xcodeproj (1.25.1)
xcodeproj (1.27.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
nanaimo (~> 0.4.0)
rexml (>= 3.3.6, < 4.0)
xcpretty (0.4.0)
rouge (~> 3.28.0)
@@ -297,7 +297,7 @@ DEPENDENCIES
cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
concurrent-ruby (< 1.3.4)
fastlane
xcodeproj (< 1.26.0)
xcodeproj (< 1.27.1)
RUBY VERSION
ruby 3.1.4p223
+3 -3
View File
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 55;
objects = {
/* Begin PBXBuildFile section */
@@ -717,7 +717,7 @@
CODE_SIGN_IDENTITY = "Apple Development: Jack Caulfield (66Z9J9NX2X)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development: Jack Caulfield (66Z9J9NX2X)";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 54;
CURRENT_PROJECT_VERSION = 58;
DEVELOPMENT_TEAM = WAH9CZ8BPG;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = WAH9CZ8BPG;
ENABLE_BITCODE = NO;
@@ -756,7 +756,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 54;
CURRENT_PROJECT_VERSION = 58;
DEVELOPMENT_TEAM = WAH9CZ8BPG;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = WAH9CZ8BPG;
INFOPLIST_FILE = Jellify/Info.plist;
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "jellify",
"version": "0.10.31",
"version": "0.10.34",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "jellify",
"version": "0.10.31",
"version": "0.10.34",
"dependencies": {
"@jellyfin/sdk": "^0.11.0",
"@react-native-community/blur": "^4.4.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jellify",
"version": "0.10.31",
"version": "0.10.34",
"private": true,
"scripts": {
"init": "npm i && npm run pod:install",
+4 -4
View File
@@ -1,8 +1,8 @@
export interface JellifyLibrary {
musicLibraryId: string;
musicLibraryName?: string;
musicLibraryPrimaryImageId?: string;
playlistLibraryId: string;
playlistLibraryPrimaryImageId?: string;
musicLibraryName?: string | undefined;
musicLibraryPrimaryImageId?: string | undefined;
playlistLibraryId?: string | undefined;
playlistLibraryPrimaryImageId?: string | undefined;
}