This repository has been archived on 2026-07-21. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
cloud-reader/mobile/src/components/reader/ReaderToolbar.tsx
T
crisleo94 22ded87250 feat: implement mobile reader
- implement mobile epub reader
2026-06-20 13:33:44 -05:00

153 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { type ReactNode } from "react";
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
import { resolvePalette } from "../../utils/epubTheme";
import type { ReadingSettings } from "../../types/reader";
interface ReaderToolbarProps {
title: string;
chapterTitle: string;
progressPct: number;
settings: ReadingSettings;
isBookmarked: boolean;
onBack: () => void;
onToggleToc: () => void;
onToggleSettings: () => void;
onToggleBookmarks: () => void;
onToggleBookmarkHere: () => void;
}
export function ReaderToolbar({
title,
chapterTitle,
progressPct,
settings,
isBookmarked,
onBack,
onToggleToc,
onToggleSettings,
onToggleBookmarks,
onToggleBookmarkHere,
}: ReaderToolbarProps): ReactNode {
const palette = resolvePalette(settings);
return (
<View style={[styles.bar, { backgroundColor: palette.chrome }]}>
<View style={styles.row}>
<TouchableOpacity
onPress={onBack}
hitSlop={12}
style={styles.iconButton}
>
<Text style={[styles.icon, { color: palette.text }]}></Text>
</TouchableOpacity>
<View style={styles.titles}>
<Text
style={[styles.title, { color: palette.text }]}
numberOfLines={1}
>
{title}
</Text>
{chapterTitle ? (
<Text
style={[styles.chapter, { color: palette.text }]}
numberOfLines={1}
>
{chapterTitle}
</Text>
) : null}
</View>
<TouchableOpacity
onPress={onToggleBookmarkHere}
hitSlop={12}
style={styles.iconButton}
>
<Text style={[styles.icon, { color: palette.text }]}>
{isBookmarked ? "★" : "☆"}
</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={onToggleBookmarks}
hitSlop={12}
style={styles.iconButton}
>
<Text style={[styles.iconSmall, { color: palette.text }]}></Text>
</TouchableOpacity>
<TouchableOpacity
onPress={onToggleToc}
hitSlop={12}
style={styles.iconButton}
>
<Text style={[styles.iconSmall, { color: palette.text }]}></Text>
</TouchableOpacity>
<TouchableOpacity
onPress={onToggleSettings}
hitSlop={12}
style={styles.iconButton}
>
<Text style={[styles.iconSmall, { color: palette.text }]}>Aa</Text>
</TouchableOpacity>
</View>
<View style={styles.progressTrack}>
<View
style={[
styles.progressFill,
{ width: `${Math.min(100, Math.max(0, progressPct))}%` },
]}
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
bar: {
paddingTop: 8,
paddingHorizontal: 8,
paddingBottom: 6,
},
row: {
flexDirection: "row",
alignItems: "center",
},
titles: {
flex: 1,
marginHorizontal: 8,
},
title: {
fontSize: 14,
fontWeight: "600",
},
chapter: {
fontSize: 11,
opacity: 0.7,
},
iconButton: {
paddingHorizontal: 8,
paddingVertical: 4,
minWidth: 28,
alignItems: "center",
},
icon: {
fontSize: 28,
lineHeight: 30,
},
iconSmall: {
fontSize: 17,
fontWeight: "600",
},
progressTrack: {
height: 3,
borderRadius: 2,
backgroundColor: "rgba(127,127,127,0.25)",
marginTop: 6,
overflow: "hidden",
},
progressFill: {
height: "100%",
backgroundColor: "#4f8ef7",
},
});