managarten/apps-archived/mukke/apps/mobile/components/MiniPlayer.tsx
Till JS 7a56699d45 feat(mukke): rename LightWrite to Mukke and add music library, player, playlists
Combines LightWrite (beat/lyrics editor) and Mukke (iOS music player) into
a single web-based music workspace app. Archives the old Mukke mobile app.

- Rename: @lightwrite/* → @mukke/*, all branding, configs, Dockerfiles
- New DB schemas: songs, playlists, playlist_songs + songId FK on projects
- New backend modules: SongModule, PlaylistModule, LibraryModule
- New web: app shell with sidebar, library (songs/albums/artists/genres),
  web player (queue/shuffle/repeat/MediaSession), playlists, search,
  upload, dashboard, album/artist/genre detail pages
- Auth: add forgot-password + reset-password pages, extend auth store
- Tests: 40 backend unit tests (song, playlist, library services)
- Config: env generation, MinIO bucket, docker-compose prod, cloudflare
- Docs: update CLAUDE.md, auth guidelines with SvelteKit checklist

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:55:56 +01:00

77 lines
2.1 KiB
TypeScript

import { Ionicons } from '@expo/vector-icons';
import { useRouter } from 'expo-router';
import { Pressable, View, Text } from 'react-native';
import { useTheme } from '~/utils/themeContext';
import { useAudio } from '~/contexts/AudioContext';
import { usePlayerStore } from '~/stores/playerStore';
import { Artwork } from './Artwork';
export function MiniPlayer() {
const { colors } = useTheme();
const router = useRouter();
const { play, pause, playNext } = useAudio();
const currentSong = usePlayerStore((s) => s.currentSong);
const isPlaying = usePlayerStore((s) => s.isPlaying);
const position = usePlayerStore((s) => s.position);
const duration = usePlayerStore((s) => s.duration);
if (!currentSong) return null;
const progress = duration > 0 ? position / duration : 0;
return (
<Pressable
onPress={() => router.push('/player')}
style={{
position: 'absolute',
bottom: 49,
left: 0,
right: 0,
backgroundColor: colors.card,
borderTopWidth: 0.5,
borderTopColor: colors.border,
}}
>
{/* Progress indicator */}
<View style={{ height: 2, backgroundColor: colors.backgroundTertiary }}>
<View
style={{
height: 2,
backgroundColor: colors.primary,
width: `${progress * 100}%`,
}}
/>
</View>
<View
style={{
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 12,
paddingVertical: 8,
}}
>
<Artwork uri={currentSong.coverArtPath} size={40} />
<View style={{ flex: 1, marginLeft: 10, minWidth: 0 }}>
<Text style={{ fontSize: 14, fontWeight: '600', color: colors.text }} numberOfLines={1}>
{currentSong.title}
</Text>
<Text style={{ fontSize: 12, color: colors.textSecondary }} numberOfLines={1}>
{currentSong.artist || 'Unbekannt'}
</Text>
</View>
<Pressable onPress={isPlaying ? pause : play} style={{ padding: 8 }}>
<Ionicons name={isPlaying ? 'pause' : 'play'} size={24} color={colors.text} />
</Pressable>
<Pressable onPress={playNext} style={{ padding: 8 }}>
<Ionicons name="play-skip-forward" size={20} color={colors.text} />
</Pressable>
</View>
</Pressable>
);
}