## Summary This PR enhances the EPUB reader's bookmark system with two complementary improvements: a per-page bookmark indicator icon and toggle behavior on the existing long-press action. --- ### What Changed **Bookmark Toggle (was: add-only)** The long-press Confirm action now toggles bookmarks rather than always adding. `addBookmark()` checks whether a bookmark with the same xpath already exists in the in-memory cache: - If found → removes it and shows "Bookmark removed." - If not found → adds it and shows "Bookmark added." A new `STR_BOOKMARK_REMOVED` translation string was added to support the removal message. **Bookmark Icon Indicator** A `BookmarkIcon` is now drawn at the top-right corner of the page whenever the current page has a bookmark. `updateBookmarkFlag()` is called at render time to determine whether the current page is bookmarked. **In-Memory Bookmark Cache** Bookmarks are now loaded into `cachedBookmarks` on `onEnter()` rather than being re-read from disk on every toggle. All subsequent add/remove operations work against this cache and flush to disk, avoiding redundant file reads on each bookmark action. **Faster bookmarks list** Previously, calculating "page X/Y" for each entry required decompressing the entire spine item. We now persist `si`/`pc`/`pp` (spine index, page count, and page progress) in the bookmark JSON when saving, and restore them when loading. This avoids the expensive `toCrossPoint()` loop in `onEnter()`, significantly reducing the cost of initializing the bookmarks list. --- ### Files Changed - `EpubReaderActivity.cpp` — `addBookmark()` toggle logic, `updateBookmarkFlag()` (new), icon rendering in `renderContents()`, cache initialization in `onEnter()` - `EpubReaderActivity.h` — new fields: `currentPageBookmarked`, `bookmarkRemoved`, `cachedBookmarks`; new method declaration `updateBookmarkFlag()` --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**< PARTIALLY >**_ --------- Co-authored-by: Julia Nguyen <julia@uxj.io>
306 lines
11 KiB
YAML
306 lines
11 KiB
YAML
_language_name: "Français"
|
||
_language_code: "FR"
|
||
_order: "2"
|
||
|
||
STR_CROSSPOINT: "CrossPoint"
|
||
STR_BOOTING: "DÉMARRAGE EN COURS"
|
||
STR_SLEEPING: "VEILLE"
|
||
STR_ENTERING_SLEEP: "Mise en veille"
|
||
STR_BROWSE_FILES: "Parcourir les fichiers"
|
||
STR_FILE_TRANSFER: "Transfert de fichiers"
|
||
STR_SETTINGS_TITLE: "Réglages"
|
||
STR_CONTINUE_READING: "Reprendre la lecture"
|
||
STR_NO_OPEN_BOOK: "Aucun livre ouvert"
|
||
STR_START_READING: "Commencer la lecture"
|
||
STR_NO_FILES_FOUND: "Aucun fichier trouvé"
|
||
STR_SELECT_CHAPTER: "Choix du chapitre"
|
||
STR_NO_CHAPTERS: "Aucun chapitre"
|
||
STR_END_OF_BOOK: "Fin du livre"
|
||
STR_EMPTY_CHAPTER: "Chapitre vide"
|
||
STR_INDEXING: "Indexation en cours"
|
||
STR_MEMORY_ERROR: "Erreur de mémoire"
|
||
STR_PAGE_LOAD_ERROR: "Erreur de chargement"
|
||
STR_EMPTY_FILE: "Fichier vide"
|
||
STR_OUT_OF_BOUNDS: "Dépassement de mémoire"
|
||
STR_LOADING: "Chargement…"
|
||
STR_LOADING_POPUP: "Chargement"
|
||
STR_WIFI_NETWORKS: "Réseaux Wi-Fi"
|
||
STR_NO_NETWORKS: "Aucun réseau"
|
||
STR_NETWORKS_FOUND: "%zu réseaux"
|
||
STR_SCANNING: "Recherche en cours…"
|
||
STR_CONNECTING: "Connexion en cours…"
|
||
STR_CONNECTED: "Connecté !"
|
||
STR_CONNECTION_FAILED: "Échec de la connexion"
|
||
STR_FORGET_NETWORK: "Oublier ce réseau ?"
|
||
STR_SAVE_PASSWORD: "Enregistrer le mot de passe ?"
|
||
STR_PRESS_OK_SCAN: "Appuyez sur OK pour scanner"
|
||
STR_JOIN_NETWORK: "Rejoindre un réseau"
|
||
STR_CREATE_HOTSPOT: "Créer un point d’accès"
|
||
STR_JOIN_DESC: "Se connecter à un Wi-Fi existant"
|
||
STR_HOTSPOT_DESC: "Créer un Wi-Fi pour d'autres appareils"
|
||
STR_STARTING_HOTSPOT: "Création du point d’accès…"
|
||
STR_HOTSPOT_MODE: "Mode point d’accès"
|
||
STR_CONNECT_WIFI_HINT: "Connectez un appareil à ce Wi-Fi"
|
||
STR_OPEN_URL_HINT: "Ouvrez cette URL dans un navigateur"
|
||
STR_OR_HTTP_PREFIX: "ou http://"
|
||
STR_SCAN_QR_HINT: "ou scannez le QR code :"
|
||
STR_CALIBRE_WIRELESS: "Connexion Calibre sans fil"
|
||
STR_NETWORK_LEGEND: "* = Sécurisé | + = Sauvegardé"
|
||
STR_MAC_ADDRESS: "Adresse MAC :"
|
||
STR_CHECKING_WIFI: "Vérification du Wi-Fi…"
|
||
STR_ENTER_WIFI_PASSWORD: "Entrez le mot de passe Wi-Fi"
|
||
STR_TO_PREFIX: "vers "
|
||
STR_CALIBRE_RECEIVING: "Réception : "
|
||
STR_CALIBRE_RECEIVED: "Reçu : "
|
||
STR_CALIBRE_INSTRUCTION_1: "1) Installer plugin CrossPoint Reader"
|
||
STR_CALIBRE_INSTRUCTION_2: "2) Être sur le même réseau Wi-Fi"
|
||
STR_CALIBRE_INSTRUCTION_3: "3) Calibre : ‘Envoyer vers l’appareil’"
|
||
STR_CALIBRE_INSTRUCTION_4: "4) Gardez cet écran ouvert"
|
||
STR_CAT_DISPLAY: "Affichage"
|
||
STR_CAT_READER: "Lecteur"
|
||
STR_CAT_CONTROLS: "Commandes"
|
||
STR_CAT_SYSTEM: "Système"
|
||
STR_SLEEP_SCREEN: "Écran de veille"
|
||
STR_SLEEP_COVER_MODE: "Mode écran de veille"
|
||
STR_HIDE_BATTERY: "Masquer % batterie"
|
||
STR_EXTRA_SPACING: "Espacement paragraphes"
|
||
STR_TEXT_AA: "Lissage du texte"
|
||
STR_IMAGES: "Images"
|
||
STR_IMAGES_DISPLAY: "Affichage"
|
||
STR_IMAGES_PLACEHOLDER: "Espace réservé"
|
||
STR_IMAGES_SUPPRESS: "Masquer"
|
||
STR_SHORT_PWR_BTN: "Appui court alim."
|
||
STR_ORIENTATION: "Orientation de lecture"
|
||
STR_SIDE_BTN_LAYOUT: "Boutons latéraux"
|
||
STR_FRONT_BTN_FOLLOW_ORIENTATION: "Orienter boutons avant"
|
||
STR_LONG_PRESS_BEHAVIOR: "Comportement lors d'un appui long"
|
||
STR_LONG_PRESS_BEHAVIOR_OFF: "Désactivé"
|
||
STR_LONG_PRESS_BEHAVIOR_SKIP: "Saut de chapitre"
|
||
STR_LONG_PRESS_BEHAVIOR_ORIENTATION: "Changement d'orientation"
|
||
STR_FONT_PREVIEW_TEXT: "Portez ce vieux whisky au juge blond qui fume"
|
||
STR_FONT_FAMILY: "Police de caractères du lecteur"
|
||
STR_FONT_SIZE: "Taille police lecteur"
|
||
STR_LINE_SPACING: "Interligne"
|
||
STR_SCREEN_MARGIN: "Marges du lecteur"
|
||
STR_PARA_ALIGNMENT: "Alignement du texte"
|
||
STR_HYPHENATION: "Césure"
|
||
STR_TIME_TO_SLEEP: "Mise en veille auto"
|
||
STR_SHOW_HIDDEN_FILES: "Afficher les fichiers cachés"
|
||
STR_REMOVE_READ_FROM_RECENTS: "Effacer les livres lus de la liste des récents"
|
||
STR_MOVE_FINISHED_TO_READ: "Déplacer les livres terminés vers le dossier Read"
|
||
STR_REFRESH_FREQ: "Fréquence rafraîchissement"
|
||
STR_KOREADER_SYNC: "Synchro KOReader"
|
||
STR_CHECK_UPDATES: "Mise à jour"
|
||
STR_LANGUAGE: "Langue"
|
||
STR_CLEAR_READING_CACHE: "Vider le cache de lecture"
|
||
STR_USERNAME: "Nom d’utilisateur"
|
||
STR_PASSWORD: "Mot de passe"
|
||
STR_SYNC_SERVER_URL: "URL du serveur"
|
||
STR_DOCUMENT_MATCHING: "Correspondance"
|
||
STR_AUTHENTICATE: "Connexion"
|
||
STR_KOREADER_USERNAME: "Utilisateur"
|
||
STR_KOREADER_PASSWORD: "Mot de passe"
|
||
STR_FILENAME: "Nom de fichier"
|
||
STR_BINARY: "Binaire"
|
||
STR_SET_CREDENTIALS_FIRST: "Identifiants manquants"
|
||
STR_WIFI_CONN_FAILED: "Échec connexion Wi-Fi"
|
||
STR_AUTHENTICATING: "Authentification…"
|
||
STR_AUTH_SUCCESS: "Authentifié !"
|
||
STR_KOREADER_AUTH: "Auth KOReader"
|
||
STR_SYNC_READY: "Synchro KOReader prête"
|
||
STR_AUTH_FAILED: "Échec authentification"
|
||
STR_DONE: "Fait"
|
||
STR_CLEAR_CACHE_WARNING_1: "Le cache de la bibliothèque sera vidé."
|
||
STR_CLEAR_CACHE_WARNING_2: "Votre progression sera perdue !"
|
||
STR_CLEAR_CACHE_WARNING_3: "Les livres devront être réindexés"
|
||
STR_CLEAR_CACHE_WARNING_4: "à la prochaine ouverture."
|
||
STR_CLEARING_CACHE: "Nettoyage du cache…"
|
||
STR_CACHE_CLEARED: "Cache vidé"
|
||
STR_ITEMS_REMOVED: "éléments supprimés"
|
||
STR_FAILED_LOWER: "ont échoué"
|
||
STR_CLEAR_CACHE_FAILED: "Échec nettoyage cache"
|
||
STR_CHECK_SERIAL_OUTPUT: "Voir console pour détails"
|
||
STR_DARK: "Sombre"
|
||
STR_LIGHT: "Clair"
|
||
STR_CUSTOM: "Personnalisé"
|
||
STR_COVER: "Couverture"
|
||
STR_NONE_OPT: "Aucun"
|
||
STR_FIT: "Ajusté"
|
||
STR_CROP: "Rogné"
|
||
STR_NEVER: "Jamais"
|
||
STR_IN_READER: "Dans le lecteur"
|
||
STR_ALWAYS: "Toujours"
|
||
STR_IGNORE: "Ignorer"
|
||
STR_SLEEP: "Mise en veille"
|
||
STR_PAGE_TURN: "Page suivante"
|
||
STR_PORTRAIT: "Portrait"
|
||
STR_LANDSCAPE_CW: "Paysage"
|
||
STR_INVERTED: "Inversé"
|
||
STR_LANDSCAPE_CCW: "Paysage inversé"
|
||
STR_PREV_NEXT: "Préc/Suiv"
|
||
STR_NEXT_PREV: "Suiv/Préc"
|
||
STR_NOTO_SERIF: "Noto Serif"
|
||
STR_NOTO_SANS: "Noto Sans"
|
||
STR_SMALL: "Petit"
|
||
STR_MEDIUM: "Moyen"
|
||
STR_LARGE: "Grand"
|
||
STR_X_LARGE: "Très grand"
|
||
STR_TIGHT: "Serré"
|
||
STR_NORMAL: "Normal"
|
||
STR_WIDE: "Large"
|
||
STR_JUSTIFY: "Justifié"
|
||
STR_ALIGN_LEFT: "Gauche"
|
||
STR_CENTER: "Centré"
|
||
STR_ALIGN_RIGHT: "Droite"
|
||
STR_PAGES_1: "1 page"
|
||
STR_PAGES_5: "5 pages"
|
||
STR_PAGES_10: "10 pages"
|
||
STR_PAGES_15: "15 pages"
|
||
STR_PAGES_30: "30 pages"
|
||
STR_UPDATE: "Mise à jour"
|
||
STR_CHECKING_UPDATE: "Recherche de mise à jour…"
|
||
STR_NEW_UPDATE: "Mise à jour disponible !"
|
||
STR_CURRENT_VERSION: "Version actuelle :"
|
||
STR_NEW_VERSION: "Nouvelle version : "
|
||
STR_UPDATING: "Mise à jour en cours…"
|
||
STR_NO_UPDATE: "Aucune mise à jour"
|
||
STR_UPDATE_FAILED: "Échec de la mise à jour"
|
||
STR_UPDATE_COMPLETE: "Mise à jour effectuée"
|
||
STR_POWER_ON_HINT: "Maintenir Power pour redémarrer"
|
||
STR_NO_ENTRIES: "Aucune entrée"
|
||
STR_DOWNLOADING: "Téléchargement…"
|
||
STR_DOWNLOAD_FAILED: "Échec du téléchargement"
|
||
STR_ERROR_MSG: "Erreur : "
|
||
STR_UNNAMED: "Sans titre"
|
||
STR_NO_SERVER_URL: "URL serveur non configurée"
|
||
STR_FETCH_FEED_FAILED: "Échec récupération flux"
|
||
STR_PARSE_FEED_FAILED: "Échec analyse flux"
|
||
STR_NETWORK_PREFIX: "Réseau : "
|
||
STR_IP_ADDRESS_PREFIX: "IP : "
|
||
STR_ERROR_GENERAL_FAILURE: "Erreur : Échec général"
|
||
STR_ERROR_NETWORK_NOT_FOUND: "Erreur : Réseau introuvable"
|
||
STR_ERROR_CONNECTION_TIMEOUT: "Erreur : Délai dépassé"
|
||
STR_SD_CARD: "Carte SD"
|
||
STR_BACK: "« Retour"
|
||
STR_EXIT: "« Quitter"
|
||
STR_HOME: "« Accueil"
|
||
STR_SELECT: "OK"
|
||
STR_SELECTED: "Sélectionné"
|
||
STR_TOGGLE: "Modifier"
|
||
STR_TOGGLE_BOOKMARK: "Basculer le marque-page"
|
||
STR_BOOKMARK_REMOVED: "Marque-page supprimé."
|
||
STR_HOLD_OPEN_TO_DELETE: "Maintenir Ouvrir pour supprimer"
|
||
STR_CONFIRM: "Confirmer"
|
||
STR_CANCEL: "Annuler"
|
||
STR_CONNECT: "Connecter"
|
||
STR_OPEN: "Ouvrir"
|
||
STR_DOWNLOAD: "Télécharger"
|
||
STR_RETRY: "Réessayer"
|
||
STR_YES: "Oui"
|
||
STR_NO: "Non"
|
||
STR_SHOW: "Afficher"
|
||
STR_HIDE: "Masquer"
|
||
STR_STATE_ON: "ON"
|
||
STR_STATE_OFF: "OFF"
|
||
STR_NOT_SET: "Non défini"
|
||
STR_DIR_LEFT: "Gauche"
|
||
STR_DIR_RIGHT: "Droite"
|
||
STR_DIR_UP: "Haut"
|
||
STR_DIR_DOWN: "Bas"
|
||
STR_OK_BUTTON: "OK"
|
||
STR_SLEEP_COVER_FILTER: "Filtre écran de veille"
|
||
STR_FILTER_CONTRAST: "Contraste"
|
||
STR_CUSTOMISE_STATUS_BAR: "Personnaliser la barre d'état"
|
||
STR_CHAPTER_PAGE_COUNT: "Nombre de pages du chapitre"
|
||
STR_BOOK_PROGRESS_PERCENTAGE: "Pourcentage de progression"
|
||
STR_PROGRESS_BAR: "Barre de progression"
|
||
STR_PROGRESS_BAR_THICKNESS: "Épaisseur de la barre"
|
||
STR_PROGRESS_BAR_THIN: "Fine"
|
||
STR_PROGRESS_BAR_MEDIUM: "Moyenne"
|
||
STR_PROGRESS_BAR_THICK: "Épaisse"
|
||
STR_BOOK: "Livre"
|
||
STR_CHAPTER: "Chapitre"
|
||
STR_EXAMPLE_CHAPTER: "Chapitre 21"
|
||
STR_EXAMPLE_BOOK: "Titre du livre"
|
||
STR_PREVIEW: "Aperçu"
|
||
STR_TITLE: "Titre"
|
||
STR_BATTERY: "Batterie"
|
||
STR_UI_THEME: "Thème interface"
|
||
STR_THEME_CLASSIC: "Classique"
|
||
STR_THEME_LYRA: "Lyra"
|
||
STR_THEME_ROUNDEDRAFF: "RoundedRaff"
|
||
STR_THEME_LYRA_EXTENDED: "Lyra Extended"
|
||
STR_SUNLIGHT_FADING_FIX: "Correction lisibilité au soleil"
|
||
STR_QUICK_RESUME_TIMEOUT: "Reprise rapide après délai"
|
||
STR_REMAP_FRONT_BUTTONS: "Configurer boutons façade"
|
||
STR_OPDS_BROWSER: "Navigateur OPDS"
|
||
STR_COVER_CUSTOM: "Couverture + Perso"
|
||
STR_QUICK_RESUME: "Reprise rapide"
|
||
STR_MENU_RECENT_BOOKS: "Livres récents"
|
||
STR_REMOVE_FROM_RECENTS: "Retirer des Livres récents ?"
|
||
STR_NO_RECENT_BOOKS: "Aucun livre récent"
|
||
STR_CALIBRE_DESC: "Utiliser transfert sans fil Calibre"
|
||
STR_FORGET_AND_REMOVE: "Oublier le réseau et le mot de passe ?"
|
||
STR_FORGET_BUTTON: "Oublier"
|
||
STR_CALIBRE_STARTING: "Démarrage Calibre…"
|
||
STR_CALIBRE_SETUP: "Configuration"
|
||
STR_CALIBRE_STATUS: "Statut"
|
||
STR_CLEAR_BUTTON: "Effacer"
|
||
STR_DEFAULT_VALUE: "Défaut"
|
||
STR_REMAP_PROMPT: "Appuyez sur un bouton façade"
|
||
STR_UNASSIGNED: "Non assigné"
|
||
STR_ALREADY_ASSIGNED: "Déjà assigné"
|
||
STR_REMAP_RESET_HINT: "Latéral haut : Réinitialiser"
|
||
STR_REMAP_CANCEL_HINT: "Latéral bas : Annuler"
|
||
STR_HW_BACK_LABEL: "Retour (Bouton 1)"
|
||
STR_HW_CONFIRM_LABEL: "OK (Bouton 2)"
|
||
STR_HW_LEFT_LABEL: "Gauche (Bouton 3)"
|
||
STR_HW_RIGHT_LABEL: "Droite (Bouton 4)"
|
||
STR_GO_TO_PERCENT: "Aller à %"
|
||
STR_GO_HOME_BUTTON: "Retour Accueil"
|
||
STR_SYNC_PROGRESS: "Synchro progression"
|
||
STR_DELETE_CACHE: "Supprimer cache livre"
|
||
STR_DELETE: "Supprimer"
|
||
STR_DISPLAY_QR: "Afficher la page en QR"
|
||
STR_CHAPTER_PREFIX: "Chapitre : "
|
||
STR_PAGES_SEPARATOR: " pages | "
|
||
STR_BOOK_PREFIX: "Livre : "
|
||
STR_CALIBRE_URL_HINT: "Pour Calibre, ajoutez /opds à l’URL"
|
||
STR_PERCENT_STEP_HINT: "Gauche/Droite : 1% Haut/Bas : 10%"
|
||
STR_SYNCING_TIME: "Synchro de l’heure…"
|
||
STR_CALC_HASH: "Calcul hash doc…"
|
||
STR_HASH_FAILED: "Échec calcul hash"
|
||
STR_FETCH_PROGRESS: "Téléchargement progression…"
|
||
STR_UPLOAD_PROGRESS: "Envoi progression…"
|
||
STR_NO_CREDENTIALS_MSG: "Aucun identifiant"
|
||
STR_KOREADER_SETUP_HINT: "Configurer compte KOReader dans réglages"
|
||
STR_PROGRESS_FOUND: "Progression trouvée !"
|
||
STR_REMOTE_LABEL: "En ligne :"
|
||
STR_LOCAL_LABEL: "Local :"
|
||
STR_PAGE_OVERALL_FORMAT: "Page %d, %.2f%% total"
|
||
STR_PAGE_TOTAL_OVERALL_FORMAT: "Page %d/%d, %.2f%% total"
|
||
STR_DEVICE_FROM_FORMAT: " De : %s"
|
||
STR_APPLY_REMOTE: "Appliquer progression en ligne"
|
||
STR_UPLOAD_LOCAL: "Envoyer progression locale"
|
||
STR_NO_REMOTE_MSG: "Aucune progression en ligne"
|
||
STR_UPLOAD_PROMPT: "Envoyer position actuelle ?"
|
||
STR_UPLOAD_SUCCESS: "Progression envoyée !"
|
||
STR_SYNC_FAILED_MSG: "Échec de la synchro"
|
||
STR_SAVE_PROGRESS_FAILED: "Échec de l'enregistrement"
|
||
STR_SECTION_PREFIX: "Section "
|
||
STR_UPLOAD: "Envoyer"
|
||
STR_BOOK_S_STYLE: "Style du livre"
|
||
STR_EMBEDDED_STYLE: "Style intégré"
|
||
STR_FOCUS_READING: "Lecture focalisée"
|
||
STR_OPDS_SERVER_URL: "URL serveur OPDS"
|
||
STR_FOOTNOTES: "Notes de bas de page"
|
||
STR_NO_FOOTNOTES: "Aucune note sur cette page"
|
||
STR_LINK: "[lien]"
|
||
STR_SLEEP_TIMER_VALUE_FORMAT: "%u min"
|
||
STR_SLEEP_NEVER: "Jamais"
|
||
STR_SLEEP_TIMER_STEP_HINT: "Gauche/Droite : 1 min Haut/Bas : 5 min"
|
||
STR_SCREENSHOT_BUTTON: "Capture d'écran"
|
||
STR_AUTO_TURN_ENABLED: "Tourne-page auto : "
|
||
STR_AUTO_TURN_PAGES_PER_MIN: "Tourne-page auto (pages par minute)"
|
||
STR_TILT_PAGE_TURN: "Tourner par inclinaison"
|