Archived
- Backend: Chapter, ReadingProgress, ReadingSettings models - Backend: Chapter API (TOC + content), progress tracking, settings CRUD - Frontend: ReadingPage with chapter navigation - Frontend: TableOfContents drawer - Frontend: ReadingSettingsPanel (theme, font, size, orientation) - Frontend: Custom hooks for settings, chapters, progress tracking - CSS: Mobile-first reading view with sepia/dark/light/paper themes - Route: /reader/:bookId reading view from book detail page - Docs: 001-customizable-mobile-reading-experience.md
63 lines
2.3 KiB
Python
63 lines
2.3 KiB
Python
from rest_framework import serializers
|
|
|
|
from apps.reader.models import ReadingSettings
|
|
|
|
# Theme presets mapped to colors
|
|
THEME_COLORS = {
|
|
"sepia": {"background_color": "#f5f0eb", "text_color": "#1a1a1a"},
|
|
"dark": {"background_color": "#1a1a2e", "text_color": "#e0e0e0"},
|
|
"light": {"background_color": "#ffffff", "text_color": "#1a1a1a"},
|
|
"paper": {"background_color": "#e8e0d4", "text_color": "#2c2c2c"},
|
|
}
|
|
|
|
|
|
class ReadingSettingsSerializer(serializers.ModelSerializer):
|
|
"""Serialize ReadingSettings for the current user."""
|
|
|
|
class Meta:
|
|
model = ReadingSettings
|
|
fields = [
|
|
"font_family",
|
|
"font_size",
|
|
"line_height",
|
|
"margin_width",
|
|
"background_color",
|
|
"text_color",
|
|
"brightness",
|
|
"orientation_lock",
|
|
"theme",
|
|
"created_at",
|
|
"updated_at",
|
|
]
|
|
read_only_fields = ["created_at", "updated_at"]
|
|
|
|
def validate_font_size(self, value: int) -> int:
|
|
if value < 12 or value > 32:
|
|
raise serializers.ValidationError("Font size must be between 12 and 32.")
|
|
return value
|
|
|
|
def validate_line_height(self, value: float) -> float:
|
|
if value < 1.2 or value > 2.0:
|
|
raise serializers.ValidationError("Line height must be between 1.2 and 2.0.")
|
|
return value
|
|
|
|
def validate_margin_width(self, value: int) -> int:
|
|
if value < 8 or value > 48:
|
|
raise serializers.ValidationError("Margin width must be between 8 and 48.")
|
|
return value
|
|
|
|
def validate_brightness(self, value: int) -> int:
|
|
if value < 0 or value > 100:
|
|
raise serializers.ValidationError("Brightness must be between 0 and 100.")
|
|
return value
|
|
|
|
def validate(self, attrs):
|
|
"""Sync theme colors when theme changes, unless explicit colors provided."""
|
|
theme = attrs.get("theme")
|
|
if theme and theme in THEME_COLORS:
|
|
# Only auto-set colors if not explicitly provided
|
|
if "background_color" not in attrs:
|
|
attrs["background_color"] = THEME_COLORS[theme]["background_color"]
|
|
if "text_color" not in attrs:
|
|
attrs["text_color"] = THEME_COLORS[theme]["text_color"]
|
|
return attrs |