Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Expose album copyright and include Typesense

Add copyright_message field to the Album GraphQL object and its
From conversions. Update frontend GraphQL query, types, and AlbumDetails
component to show copyright and a formatted release date. Dockerfile
now pulls the typesense image and copies typesense-server into the
final image.

+66
+4
Dockerfile
··· 67 67 68 68 RUN [ -n "$TAG" ] && fluentci run --wasm . release ; exit 0 69 69 70 + FROM typesense/typesense:30.1 AS typesense 71 + 70 72 FROM debian:bookworm 71 73 72 74 RUN apt-get update && apt-get install -y \ ··· 83 85 COPY --from=builder /usr/local/share/rockbox /usr/local/share/rockbox 84 86 85 87 COPY --from=builder /usr/local/bin/rockboxd /usr/local/bin/rockboxd 88 + 89 + COPY --from=typesense /opt/typesense-server /usr/local/bin/typesense-server 86 90 87 91 ENV SDL_VIDEODRIVER=dummy 88 92
+7
crates/graphql/src/schema/objects/album.rs
··· 12 12 pub album_art: Option<String>, 13 13 pub md5: String, 14 14 pub artist_id: String, 15 + pub copyright_message: Option<String>, 15 16 pub tracks: Vec<Track>, 16 17 } 17 18 ··· 49 50 &self.artist_id 50 51 } 51 52 53 + async fn copyright_message(&self) -> Option<&str> { 54 + self.copyright_message.as_deref() 55 + } 56 + 52 57 async fn tracks(&self) -> Vec<Track> { 53 58 self.tracks.clone() 54 59 } ··· 65 70 album_art: album.album_art, 66 71 md5: album.md5, 67 72 artist_id: album.artist_id, 73 + copyright_message: album.copyright_message, 68 74 tracks: vec![], 69 75 } 70 76 } ··· 81 87 album_art: album.album_art, 82 88 md5: album.md5, 83 89 artist_id: album.artist_id, 90 + copyright_message: None, 84 91 tracks: vec![], 85 92 } 86 93 }
+32
webui/rockbox/src/Components/AlbumDetails/AlbumDetails.tsx
··· 20 20 BackButton, 21 21 Label, 22 22 Link, 23 + Footer, 24 + FooterText, 23 25 } from "./styles"; 24 26 import Button from "../Button"; 25 27 import ArrowBack from "../Icons/ArrowBack"; ··· 33 35 import _ from "lodash"; 34 36 import DetailHeaderSkeleton from "../Skeletons/DetailHeaderSkeleton"; 35 37 import TrackListSkeleton from "../Skeletons/TrackListSkeleton"; 38 + 39 + const MONTHS = [ 40 + "January", "February", "March", "April", "May", "June", 41 + "July", "August", "September", "October", "November", "December", 42 + ]; 43 + 44 + function formatReleaseDate(s: string): string { 45 + const parts = s.split("-"); 46 + if (parts.length === 3) { 47 + const y = parseInt(parts[0], 10); 48 + const m = parseInt(parts[1], 10); 49 + const d = parseInt(parts[2], 10); 50 + if (!isNaN(y) && !isNaN(m) && !isNaN(d) && m >= 1 && m <= 12) { 51 + return `${d} ${MONTHS[m - 1]} ${y}`; 52 + } 53 + } 54 + return s; 55 + } 36 56 37 57 const columnHelper = createColumnHelper<Track>(); 38 58 ··· 213 233 </div> 214 234 ))} 215 235 </div> 236 + )} 237 + {(props.album?.yearString || props.album?.copyrightMessage) && ( 238 + <Footer> 239 + {props.album?.yearString && ( 240 + <FooterText> 241 + {formatReleaseDate(props.album.yearString)} 242 + </FooterText> 243 + )} 244 + {props.album?.copyrightMessage && ( 245 + <FooterText>{props.album.copyrightMessage}</FooterText> 246 + )} 247 + </Footer> 216 248 )} 217 249 </div>} 218 250 </ContentWrapper>
+9
webui/rockbox/src/Components/AlbumDetails/__snapshots__/AlbumDetails.test.tsx.snap
··· 2966 2966 </tr> 2967 2967 </tbody> 2968 2968 </table> 2969 + <div 2970 + class="css-rimww3" 2971 + > 2972 + <div 2973 + class="css-ngpkdm" 2974 + > 2975 + 2006 2976 + </div> 2977 + </div> 2969 2978 </div> 2970 2979 </div> 2971 2980 </div>
+12
webui/rockbox/src/Components/AlbumDetails/styles.tsx
··· 134 134 text-decoration: underline; 135 135 } 136 136 `; 137 + 138 + export const Footer = styled.div` 139 + display: flex; 140 + flex-direction: column; 141 + gap: 4px; 142 + padding: 24px 0 32px; 143 + `; 144 + 145 + export const FooterText = styled.div` 146 + font-size: 12px; 147 + color: ${(props) => props.theme.colors.secondaryText}; 148 + `;
+1
webui/rockbox/src/GraphQL/Library/Query.ts
··· 98 98 yearString 99 99 artistId 100 100 md5 101 + copyrightMessage 101 102 tracks { 102 103 id 103 104 title
+1
webui/rockbox/src/Hooks/GraphQL.tsx
··· 22 22 albumArt?: Maybe<Scalars['String']['output']>; 23 23 artist: Scalars['String']['output']; 24 24 artistId: Scalars['String']['output']; 25 + copyrightMessage?: Maybe<Scalars['String']['output']>; 25 26 id: Scalars['String']['output']; 26 27 md5: Scalars['String']['output']; 27 28 title: Scalars['String']['output'];