Compare commits

...

210 Commits

Author SHA1 Message Date
Huang Xin 267e1656db release: version 0.9.30 (#817) 2025-04-05 11:39:37 +02:00
Huang Xin dcecda2984 fix: cache NativeFile with LRU, closes #797 (#816) 2025-04-05 11:27:07 +02:00
Huang Xin ce88f0229a fix: rounded reader widget only when sidebar is invisible , closes #809 (#815) 2025-04-05 10:08:39 +02:00
Huang Xin 316c82ea52 fix: override link color only when overriding font, closes #812 (#814) 2025-04-05 09:34:29 +02:00
Huang Xin 25be60ce2a chore: bump tauri to 2.4.1 (#813) 2025-04-05 07:40:33 +02:00
Huang Xin 4703eec045 fix: set correct filename in openFile API, closes #803 (#810) 2025-04-05 12:41:26 +08:00
Huang Xin ab22a83332 fix: open default file chooser on Android, closes #798 and closes #799 (#807) 2025-04-04 05:01:12 +02:00
Huang Xin a3d6ebe44d feat: add fixed storage quota for self-hosted instance, closes #805 (#806) 2025-04-04 03:48:43 +02:00
Huang Xin f8804b5d3c fix: revert font family, size and color when overrideFont is set, closes #792 (#804) 2025-04-03 17:15:19 +02:00
Huang Xin ee3785ad51 fix: hack to decode incorrectly encoded url in href (#796) 2025-04-02 07:35:00 +02:00
Huang Xin 5ba40cd2d6 release: version 0.9.29 (#790) 2025-04-01 18:27:15 +02:00
Huang Xin 6131180a31 fix: initiate OAuth using Custom Tabs on Android, closes #361 (#788) 2025-04-01 17:04:17 +02:00
Huang Xin 7ccf3d0632 refactor: read local file with fs plugin for Tauri App, closes #553 and closes #489 (#785) 2025-04-01 14:26:26 +02:00
Huang Xin 39fb7f759e fix: handle preflight on tauri apps (#776) 2025-03-31 03:38:47 +02:00
Huang Xin d89834a53d chore: balance translator load between auth and guest users (#771) 2025-03-30 16:35:13 +02:00
Huang Xin 3c4dd2a143 fix: fix translation api with retry (#770) 2025-03-30 15:59:57 +02:00
Huang Xin 847efb7082 fix: head bar may hide login buttons in auth page (#769) 2025-03-30 11:32:57 +02:00
Huang Xin 01db8f90fa fix: store the filepath for transient import, closes #760 (#768) 2025-03-30 10:27:45 +02:00
Huang Xin e70c46ff02 fix: only replace quote punctuations for vertical layout, closes #761 (#767) 2025-03-30 09:49:22 +02:00
Huang Xin 7cb1998ebb fix: soft keyboard in custom css textarea, closes #762 and closes #763 (#766) 2025-03-30 09:33:27 +02:00
Huang Xin f5fd37f40d release: version 0.9.28 (hotfix) (#759) 2025-03-29 19:46:09 +01:00
Huang Xin 2daee62b80 fix: dismiss highlighting tools for annotation taking (#758) 2025-03-29 19:40:37 +01:00
Huang Xin ffd179bb06 fix: TXT file correctly read and imported on desktop apps, closes #756 (#757) 2025-03-29 19:11:41 +01:00
Huang Xin 4acc0d8e12 feat: replace punctuation marks in vertical reading mode (#754) 2025-03-29 12:42:23 +01:00
Huang Xin a66786444f release: version 0.9.27 (#751) 2025-03-29 08:03:38 +01:00
Huang Xin 01ad18ca57 feat: global fulltext search shortcut with ctrl/cmd+f (#750) 2025-03-29 07:45:41 +01:00
Huang Xin a72c8f2391 refactor: rename plugin safari-auth to native-bridge (#749)
* fix: layout tweaks for mobile

* refactor: rename plugin safari-auth to native-bridge
2025-03-29 07:27:18 +01:00
Huang Xin f90177713a tts: avoid pauses after abbreviations, faster warming up, preferred voice ids (#742) 2025-03-28 13:25:08 +01:00
Huang Xin 041eb1b921 feat: support more languages in deepl translator (#740) 2025-03-28 07:31:34 +01:00
Huang Xin 105302d241 fix: don't crash with some malformed toc data for PDF, closes #518 (#739) 2025-03-28 06:54:32 +01:00
Huang Xin bd9c7b459c fix: avoid stale values in relocate handler, closes #736 (#738) 2025-03-28 06:33:51 +01:00
Huang Xin 1c122752bb fix: update downloadedAt field properly (#737) 2025-03-28 06:03:18 +01:00
Huang Xin 203ef8b986 feat: add reset password page, closes #700 (#731) 2025-03-28 03:52:04 +08:00
Huang Xin ceda806f77 fix: override book writing-mode (#730) 2025-03-27 15:53:35 +01:00
Huang Xin baac9dfa25 fix: unhardcode background color in non-default themes (#729) 2025-03-27 13:05:03 +01:00
Huang Xin 10aace0026 fix: avoid view glitch when initialize view settings, closes #713 (#728) 2025-03-27 12:40:41 +01:00
Huang Xin 3e38896078 feat: add option to swap click-to-flip area, closes #719 (#727) 2025-03-27 11:35:57 +01:00
Huang Xin 0fa53c5f15 fix: should listen single-instance event on Windows to open-with files, closes #724 (#726) 2025-03-27 09:11:03 +01:00
Xi Gou 2b6320b880 refactor: support both r2 and s3 storage (#718) 2025-03-27 07:00:27 +01:00
Huang Xin 7ba938ea25 fix: header layout for auth and user pages (#725) 2025-03-27 05:14:38 +01:00
Huang Xin 6d4ad34e32 release: version 0.9.26 (#723) 2025-03-26 17:44:26 +01:00
Huang Xin 3239ff0a80 feat: add LXGW WenKai to serif fonts list (#722) 2025-03-26 17:28:14 +01:00
Huang Xin 8b7e3c6f79 fix: textarea hidden behind keyboard in fullscreen Android app. closes #653 (#720) 2025-03-26 15:57:35 +01:00
Huang Xin ace4b78420 fix: uncrash scroll prev at start and scroll next at end (#712) 2025-03-26 12:42:39 +01:00
Huang Xin 39ac89fead fix: don't override bg color for img, closes #656 (#711) 2025-03-26 12:23:46 +01:00
Huang Xin 490fe7e70c ui: fix library header padding (#710) 2025-03-26 09:07:38 +01:00
Huang Xin 06a7a8ea82 feat: add option for transient import from file managers, closes #456 (#709) 2025-03-26 07:11:47 +01:00
Huang Xin b7f4a3503f doc: add TXT to supported formats list (#708)
* fix: set max width for annotation toolbar

* doc: add TXT to supported formats list
2025-03-26 11:45:56 +08:00
Huang Xin 835ed443a5 fix: style tweaks for Windows (#707) 2025-03-25 18:58:23 +01:00
Huang Xin 3f3c6983ba fix: also export newly created annotations (#704) 2025-03-25 06:26:11 +01:00
Huang Xin f22ce1c225 fix: access runtime variables in function invoke (#703) 2025-03-25 05:29:22 +01:00
Huang Xin 9990de112f chore: bump updates of next.js and tauri (#702) 2025-03-25 04:46:07 +01:00
Huang Xin ede37757db chore: support deploy in cloudflare with opennext and fix android build 2025-03-25 03:52:04 +08:00
Huang Xin 0c65d44bc9 chore: add android release in github actions (#695) 2025-03-25 01:57:05 +08:00
Huang Xin 07c9813ec1 fix: no background color for section and page info in vertical scroll mode (#694) 2025-03-24 07:13:38 +01:00
Huang Xin 03f0ee1f7d release: version 0.9.25 (#690) 2025-03-23 19:39:39 +01:00
Huang Xin ebc23c4ce3 feat: export annotations in markdown format, closes #152 (#689) 2025-03-23 19:33:05 +01:00
Huang Xin d098487cd1 fix: add metadata parsed from cbz zip comment, closes #639 (#688) 2025-03-23 18:18:08 +01:00
Huang Xin 14f2db730a fix: add option to override justify style in books, closes #671 (#687) 2025-03-23 16:59:45 +01:00
Huang Xin a79f301165 feat: add language preference options in settings (#686) 2025-03-23 16:39:58 +01:00
Huang Xin 05d086352f chore: add f-droid metadata (#682) 2025-03-23 08:59:34 +01:00
Huang Xin ef864a32c2 feat: action bar at the bottom on mobile devices (#681) 2025-03-23 08:56:57 +01:00
Huang Xin 0d93a13407 fix: format footer in popup window (#665) 2025-03-21 05:52:56 +01:00
Huang Xin ab0208b7ab fix: now img in paragraph won't get indented and default to override book layout (#657) 2025-03-20 17:10:26 +01:00
Huang Xin c52f3c0430 feat: support importing TXT files, closes #308 (#655) 2025-03-20 15:00:30 +01:00
Huang Xin accf6fb5c7 feat: snap dialog to preview effects of book settings adjustments (#646) 2025-03-19 14:23:52 +01:00
Huang Xin 18c2ce1274 fix: various fixes on layout settings and styles, closes #637 (#644) 2025-03-19 10:14:02 +01:00
Huang Xin 9a104b918c fix: dismiss popup footnotes on window resize, also closes #634 and closes #635 (#638) 2025-03-19 04:22:15 +01:00
Huang Xin 948303c43a release: version 0.9.23 (#633) 2025-03-18 17:13:43 +01:00
Huang Xin 82f303fcfe feat: responsive window size for popup footnotes, closes #538 (#632) 2025-03-18 17:00:07 +01:00
Huang Xin 359fa8df35 refactor: always save when changes are made with settings, also closes #626 (#630) 2025-03-18 12:58:01 +01:00
Huang Xin 72e6c058f5 fix: completed books now have 100% progress (#625) 2025-03-18 06:00:33 +01:00
Huang Xin 7648aa47b2 fix: don't reinit footnote handler when theme is changed, closes #619 (#621) 2025-03-17 17:47:31 +01:00
Huang Xin 48074f0f53 feat: add options to show/hide header and footer widgets in paginated and scrolled mode, also closes #602 (#620) 2025-03-17 15:30:12 +01:00
Huang Xin 66bd8d74f3 fix: also set color-scheme in iframe for Safari (#616) 2025-03-17 05:53:42 +01:00
Huang Xin 37f3c8b829 chore: fix node out of memory when building 2025-03-16 03:43:32 +08:00
Huang Xin 8775f90bc1 fix: refresh page when vertical writing mode is set (#615) 2025-03-15 20:07:54 +01:00
Huang Xin d6962055b9 release: version 0.9.22 (#614) 2025-03-15 19:43:44 +01:00
Huang Xin 05489282df cjk: always show vertical layout options in CJK locale (#613) 2025-03-15 19:37:05 +01:00
Huang Xin 58f1b5833f feat: add border frame for vertical layout, also closes #563 (#612) 2025-03-15 18:55:12 +01:00
Huang Xin c66911b060 fix: hiding scrollbars may cause layout changes, closes #600 (#610) 2025-03-15 06:38:48 +01:00
Huang Xin 54debbfe86 api: load balance of translation requests (#609) 2025-03-15 05:24:34 +01:00
Huang Xin 6d580565fd fix: use deepl jsonrpc for free plan translation (#608) 2025-03-14 18:31:51 +01:00
Huang Xin f0270eec4e fix: handle system theme change and set color scheme, closes #571 (#607) 2025-03-14 16:55:27 +01:00
Huang Xin cd9290240a fix: force focus on dropdown menu on older Safari, closes #574 (#606) 2025-03-14 10:14:24 +01:00
Huang Xin 2fc7bc4744 fix: don't handle iframe wheel events for scrolled mode, closes #604 (#605) 2025-03-14 08:43:50 +01:00
Huang Xin 5370a9e7f6 bump: bump update next.js to 15.2.2 (#601) 2025-03-13 19:03:21 +01:00
Huang Xin 08f348ada5 fix: don't hide horizontal scroll bar at the bottom, closes #570 (#599) 2025-03-13 17:45:41 +01:00
Huang Xin 4452f0b810 fix: prevent the footer bar from popping up by tapping at the bottom on mobile devices, closes #597 (#598) 2025-03-13 17:19:31 +01:00
Huang Xin b7dc880a5e feat: add scrolled mode toggler in font/layout settings dialog, closes #580 (#596) 2025-03-13 15:07:17 +01:00
Huang Xin 35596094c2 fix: clear select mode when importing files, closes #581 (#595) 2025-03-13 14:41:19 +01:00
Huang Xin e8eb409f9f feat: add theme editor for custom theme colors, closes #462 (#594) 2025-03-13 14:23:58 +01:00
Huang Xin 6a74a0c5b8 fix: following ordinary link in footnotes, closes #559 (#560) 2025-03-10 18:09:47 +01:00
Huang Xin dfa0468d24 release: hot fix version 0.9.21 (#551)
* sync: update partial config to sync more actively

* rtl: make the order of go back/forward buttons consistent

* fix: wheel events conflict with touchpad scroll on macOS

* release: hot fix version 0.9.21
2025-03-09 20:22:47 +01:00
Huang Xin 4869b756ea release: version 0.9.20 (#549)
* fix: occasionally traffic lights disappear in library page

* release: version 0.9.20
2025-03-09 17:40:30 +01:00
Huang Xin 693c79c9b7 fix: remove seldomly used option to invert colors in dark mode (#548)
This option is hard to understand and explain. Most hardcoded color
in dark mode that affects readability has already been fixed in the
reader so there is no necessity to have this option.
2025-03-09 17:02:01 +01:00
Huang Xin e846875973 doc: update screenshots in readme (#546) 2025-03-09 14:15:41 +01:00
Huang Xin b1f2941247 fix: various fixes for updater, footerbar and note item (#545)
* fix: don't open book if failed to download book

* fix: various fixes for updater, footerbar and note item
1. now footerbar when invisible won't process pointer events
2. manually check updater won't be prevented by check interval
3. get rid of clamped text in note item
2025-03-09 11:33:52 +01:00
Huang Xin 6688c813e6 fix: don't open book if failed to download book (#541) 2025-03-09 10:29:16 +01:00
Huang Xin 664dc45fcc fix: search options menu in mobile & user id in posthog (#539) 2025-03-09 07:07:42 +01:00
Huang Xin 27fa753486 feat: support drag and drop to import books, closes #524 (#536) 2025-03-08 19:12:00 +01:00
Huang Xin 71e392544c fix: rtl for notebook, closes #451 (#535) 2025-03-08 16:51:24 +01:00
Huang Xin 7f24081205 feat: add fullscreen option for desktop app, closes #493 (#534) 2025-03-08 22:36:25 +08:00
Huang Xin 89f1c43984 fix: don't hide horizontal scrollbar at the bottom, closes #515 (#533) 2025-03-08 21:26:10 +08:00
Huang Xin f841004e7a chore: bump update of tauri (#532) 2025-03-08 10:53:31 +01:00
Huang Xin 0922f557bb fix: make the height of the drag handle in dialog stable (#530) 2025-03-08 10:03:00 +01:00
Huang Xin 0b72ab156d refactor: move useTheme hook into separate store, also closes #528 (#529) 2025-03-08 09:12:36 +01:00
Huang Xin dfc6cc9c8a Update feature-request template 2025-03-08 04:02:02 +01:00
Huang Xin 83b2908266 compat: replace absolute font sizes with rem units in css, closes #521 (#523) 2025-03-07 18:37:46 +01:00
Huang Xin c25f2a7abc fix: make continuous scroll an option and disabled by default, closes #516, #373 (#522) 2025-03-07 17:24:01 +01:00
Huang Xin de1e396f6e fix: switch label for column width/height for vertical layout and fix column size calculation (#520)
* fix: scroll mode should be updated when calculating column size

* fix: switch label for column width/height for vertical layout, closes #517
2025-03-07 16:42:40 +01:00
Huajin 80a3861816 Fixes the scrollbar gutter issue for DaisyUI (#514)
* Fixes the scrollbar gutter issue for DaisyUI
https://github.com/saadeghi/daisyui/issues/3040#issuecomment-2250530354
2025-03-07 15:15:52 +01:00
Huang Xin fd8eeb07c2 fix: set sidebar rtl only for mandatory rtl languages, closes #512 (#519) 2025-03-07 15:06:12 +01:00
Huang Xin 93d1fe6946 release: version 0.9.19 (#508) 2025-03-06 17:30:48 +01:00
Huang Xin 3c52a9e0cb feat: customize foliate view styles with css, closes #167 (#507) 2025-03-06 17:22:01 +01:00
Huang Xin 3056a29860 compat: handle epub files without dc metadata, closes #490 (#506) 2025-03-06 16:44:07 +01:00
Huang Xin bd6738e54c fix: release wakelock when window or tab lost focus, closes #502 (#505) 2025-03-06 16:23:58 +01:00
Huang Xin 8c3f49de25 rtl: support rtl for more widgets in sidebar (#504) 2025-03-06 15:38:29 +01:00
Huang Xin 0f44fff7cd feat: support styled reader UI via custom CSS, closes #240 (#503) 2025-03-06 13:56:43 +01:00
Huang Xin 77bba7bd0c fix: use section info for PDF progress bar, closes #158 (#501) 2025-03-06 11:22:06 +01:00
Huang Xin d30d1c17ae rtl: rtl page layout from settings and book language, closes #359 (#500) 2025-03-06 10:58:32 +01:00
nnecec 088c7d2c49 fix: various tweaks on style and layout (#499) 2025-03-06 10:51:06 +01:00
Huang Xin d0e6f3ad50 fix: ensure the progress bar direction is consistent with the book’s writing direction, closes #451 (#498) 2025-03-06 09:14:33 +01:00
Huang Xin 8a83389164 fix: hide traffic lights when sidebar is invisible on macOS, closes #297 (#497) 2025-03-06 07:14:23 +01:00
Huang Xin 04d07856f5 fix: use client timestamp for updated records, closes #468 (#488) 2025-03-04 14:26:30 +01:00
Huang Xin cc8d0ea457 fix: filter deleted books in parallel read menu, closes #476 (#487) 2025-03-04 07:18:54 +01:00
Huang Xin 29e6af7768 fix: handle hardcoded border color of chapter header for Feedbooks, closes #470 (#485) 2025-03-04 06:02:18 +01:00
Huang Xin bc70d07749 fix: support footnotes with links inside of the lists, closes #472 (#479) 2025-03-03 16:27:03 +01:00
Huang Xin 2db83b8569 ui: responsive dialog size for portrait screens (#473)
* fix: handle network error in sync API

* fix: reasonable default column width for iPad

* ui: responsive dialog size for portrait screens
2025-03-01 17:57:29 +01:00
Huang Xin 2f29295c6c fix: open with new files from file browsers when there is already an instance running, closes #208 (#466) 2025-02-28 08:42:49 +01:00
Huang Xin cab757257e release: version 0.9.18 (#458) 2025-02-26 19:42:11 +01:00
Huang Xin fc8c9546b6 fix: normalize language code for TTS (#457) 2025-02-26 19:30:22 +01:00
Huang Xin 3cc41b7b71 auth: redirect to auth page when callback page has no token (#454) 2025-02-26 01:31:50 +01:00
Huang Xin e65380aaf5 ui: use less saturated and modern colors when drawing highlights (#453) 2025-02-26 00:45:33 +01:00
Huang Xin 24b68ac046 feat: add user profile page and option to delete account in the cloud (#452) 2025-02-26 00:16:42 +01:00
Huang Xin e0591ce41c ui: style tweaks on Popup and Dialog (#448) 2025-02-25 15:49:27 +01:00
Huang Xin 7be6c07344 ux: enhancements on iOS with modals and annotation tools (#447)
* mobile: auto save progress also for iOS

* ux: enhancements on pull-down to dismiss modals

* doc: update reademe

* ux: tricks to dismiss system selection tools on iOS
2025-02-25 13:07:44 +01:00
Huang Xin f8ea7fc463 chore: add stub android plugin for safari-auth (#443) 2025-02-24 11:41:26 +01:00
Huang Xin 36e09582bc release: version 0.9.17 (#441) 2025-02-24 01:24:28 +01:00
Huang Xin ccc04825b7 feat(ux): improve pull-down interaction for mobile modal (#440)
* Adjusts overlay background opacity dynamically based on drag position
* Ensures smooth transition as the modal is pulled down
* Enhances UX for mobile users by making dismissal more intuitive
2025-02-24 01:05:13 +01:00
Huang Xin 9e7e41a623 fix: prerender library page without localStorage (#439) 2025-02-23 17:04:02 +01:00
Huang Xin 1ff929ece5 feat: add toggle select mode and quit app shortcuts in library page, closes #96 (#438) 2025-02-23 16:46:51 +01:00
Huang Xin 4c7b7881c8 feat: add d/u shortcuts for half page navigation, closes #62 (#437) 2025-02-23 15:56:00 +01:00
Huang Xin 1d5b189185 fix: preserve note id when changing style and preserve style when changing color, closes #252 (#436) 2025-02-23 15:32:57 +01:00
Huang Xin a9aa2fe7a4 fix: set minimum font size for obsolete font tag, closes #434 (#435) 2025-02-23 13:42:37 +01:00
Huang Xin 0253afca86 auth: add safari-auth plugin for iOS OAuth (#433)
* auth: add safari-auth plugin for iOS OAuth

* fix: temporarily disable email auth provider for iOS
2025-02-23 03:31:10 +01:00
Ahmed 7ddbaa644b Add arabic localization (#432)
* Add arabic localization

* Add 'ar' lang to scanner config

* Add 'ar' lang to scanner config
2025-02-22 21:51:20 +01:00
Huang Xin e96782baab api: load balance of the API keys for deepl translate, closes #429 (#431) 2025-02-22 09:09:25 +01:00
Gigoo25 66784736ee Add Dockerfile to selfhost (#430) 2025-02-22 08:03:12 +01:00
Huang Xin 2bb6ed2602 feat: add haptics feedback when entering select mode (#428) 2025-02-22 00:18:06 +01:00
Huang Xin 48ef2d634f chore: fix aarch64 linux build 2025-02-21 20:09:18 +01:00
Huang Xin e77c377839 release: version 0.9.15 (#425) 2025-02-21 19:44:28 +01:00
Huang Xin c2d75deab4 fix: override font color from calibre (#422) 2025-02-21 17:07:27 +01:00
Huang Xin e7579e5867 ui: wrap keyboard shortcuts in kbd tag (#421) 2025-02-21 16:43:38 +01:00
Huang Xin fcc933a243 doc: add instruction for starting development for the Web version only 2025-02-21 16:08:19 +01:00
Huang Xin bbc457a9a5 fix: scroll to current TOC item when toggling sidebar, closes #418 (#420) 2025-02-21 14:18:00 +01:00
Huang Xin f8bd4a0e2c doc: update feature-request template 2025-02-21 12:52:52 +01:00
Huang Xin 3ada880155 ui: fix os platform detection for iPad and layout tweaks for iPad (#416) 2025-02-21 01:11:33 +01:00
Huang Xin 66866372ea ui: responsive font size for book notes (#415) 2025-02-20 12:02:55 +01:00
Huang Xin b321986c40 fix: display complete notes in note list and save note drafts, closes #405 (#412) 2025-02-20 02:13:33 +01:00
Huang Xin 829a698ece auth: use native sign in with Apple on iOS & i18n for auth page (#411) 2025-02-19 23:49:15 +01:00
Huang Xin 978a512ebf mobile: enable paging animation by default on mobile platforms (#410) 2025-02-19 20:27:22 +01:00
Huang Xin aca8c93efb fix: avoid repeative navigation to login after closing login page (#409) 2025-02-19 17:21:03 +01:00
Huang Xin 8cb81b3795 release: version 0.9.13 (#404) 2025-02-19 01:20:16 +01:00
Huang Xin 91716df5e0 feat: add option to keep screen awake when reading (#403) 2025-02-19 00:33:23 +01:00
Huang Xin f5f07e9392 fix: handle malformed href in PDF TOC, closes #357 (#402) 2025-02-18 23:29:23 +01:00
Huang Xin 7e385db4ed compat: support weread footernote, closes #391 (#401) 2025-02-18 22:23:05 +01:00
Huang Xin 1b99915663 fix: override some styles to show footnotes, closes #383 (#400) 2025-02-18 21:12:56 +01:00
Huang Xin 0a213d6a0e chore: clean up oauth callback (#399) 2025-02-18 18:12:25 +01:00
Huang Xin f9e9c90386 fix: swipe gesture in library page should not unintentionally trigger tap (#396) 2025-02-18 13:29:07 +01:00
Huang Xin 8b2888af34 ui: fix title bar padding in the library page (#395) 2025-02-18 12:42:45 +01:00
Huang Xin ffb00f4e0d ux: make the top and bottom toolbar transient and hide in normal reading status (#394) 2025-02-18 12:07:04 +01:00
Huang Xin 77da5423a6 ui: fix notebook layout (#392) 2025-02-17 23:23:24 +01:00
Huang Xin ee201d4571 ui: fix alert position in BookDetailModal and toast content max width (#390) 2025-02-17 14:05:18 +01:00
Huang Xin e48cfc407c release: script for iOS appstore upload (#388) 2025-02-16 20:50:57 +01:00
Huang Xin d49be1f9ca ui: fix alert layout not centered after refactoring (#387) 2025-02-16 15:50:28 +01:00
Huang Xin c46cf5b0bf UX enhancements of grid view in mobile platforms (#379)
* ux: context menu on both group and book items, also closes #376

* ui: more compact grid view of bookshelf on mobile platforms
2025-02-16 01:02:41 +01:00
jackplo 3078b09ba4 FR #241: Added Shortcuts to notetaking UI (#378) 2025-02-15 22:28:33 +01:00
Huang Xin 05cb53ede4 fix: use mouse pos in screen coordinates for click-to-flip, closes #351 (#375) 2025-02-15 02:34:17 +01:00
Huang Xin bd6ef7fe8e release: version 0.9.11
* ui: tweaks on header bar layout

* release: build arm64 linux binaries
2025-02-14 02:31:03 +01:00
Huang Xin b33d85f439 ui: fix layout in mobile platforms (#371) 2025-02-14 00:19:25 +01:00
Huang Xin 95a69d6bdf ux: polish ux of grouping dialog (#370) 2025-02-13 22:49:59 +01:00
Huang Xin ed9a0c6f20 ux: hide action bar when modal is shown (#369) 2025-02-13 21:34:56 +01:00
Huang Xin 71b075dfa8 feat: organize the library with groups (#368) 2025-02-13 18:45:57 +01:00
Huang Xin 937832a8ee ui: fix toast position on mobile devices (#350) 2025-02-10 23:15:43 +01:00
Huang Xin 881a54f155 cjk: default text indent for CJK and fix unusual OEBPS naming, closes #346 (#349) 2025-02-10 22:05:58 +01:00
Huang Xin 2dd0a20925 fix: reintroduce hold detection to avoid unwanted single click (#348) 2025-02-10 20:31:27 +01:00
Huang Xin b7ae3f29d9 chore: support deployment with open-next on cloudflare (#347) 2025-02-10 19:28:06 +01:00
Huang Xin 609ddb776b ux: disable double click timeout on mobile devices for more performant page turning (#339) 2025-02-09 21:36:08 +01:00
Huang Xin 7847360588 cjk: set full justification by default for CJK even on mobile devices (#338) 2025-02-09 20:32:30 +01:00
Huang Xin 8e7240bb9b ux: process synced books in update time ascending order (#337) 2025-02-09 18:58:56 +01:00
Huang Xin effbc08561 mobile: use sticky position for action bars for mobile compatibility (#335) 2025-02-09 18:35:24 +01:00
Huang Xin 6b057ebc14 feat: add override option for paragraph spacing settings, closes #329 (#334) 2025-02-09 16:05:37 +01:00
Huang Xin 26b64adca6 fix: add blob CSP for font and don't override <p> margin by default (#327)
* android: add fullscreen theme

* fix: add blob CSP for font and don't override <p> margin by default, closes #320
2025-02-09 00:54:06 +01:00
Huang Xin 9577f6a026 android: compatibility for Android 8 (#326) 2025-02-08 20:02:05 +01:00
Huang Xin 25da9210e2 readme: update roadmap and badge-platforms (#325) 2025-02-08 19:04:24 +01:00
Huang Xin 8b80c52c54 release: version 0.9.10 (#324) 2025-02-08 18:53:50 +01:00
Huang Xin d3d496b583 mobile: fix TTS icon position on iOS (#322) 2025-02-08 18:21:47 +01:00
Huang Xin ad1365fa23 mobile: fix layout of book detail modal and refresh indicator (#321) 2025-02-08 17:57:49 +01:00
Huang Xin 0ba3b510ce fix: importing fb2.zip file and CSP for embedded cover image (#319)
* fix: don't set window shadow below Win 11

* fix: importing fb2.zip file and CSP for embedded cover image
2025-02-08 16:19:54 +01:00
Huang Xin 1da0817145 mobile: fix sidebar height on iOS (#318)
* mobile: fix sidebar height on iOS

* fix: tts should not resume playing when closing book
2025-02-08 13:32:15 +01:00
Huang Xin 151509b84c mobile: fix iOS safe area insets (#317) 2025-02-08 03:38:17 +01:00
Huang Xin 282b129bf5 mobile: save book config when progress changes on Android (#315) 2025-02-07 23:22:55 +01:00
Huang Xin 7dfd7b9ca2 mobile: fix hasSafeAreaInset as PWA is only for WebAppService (#314) 2025-02-07 22:35:24 +01:00
Huang Xin ce00c3e923 mobile: immersive UI for android (#313) 2025-02-07 22:23:42 +01:00
Huang Xin e2e3418412 mobile: support safe area insets for mobile platforms (#312) 2025-02-07 22:15:18 +01:00
Huang Xin c79657a1ee fix: don't autoscroll to current item in TOC when TTS is on (#311) 2025-02-07 19:08:50 +01:00
Huang Xin dee1e28a61 feat: add options to adjust paragraph margin, word spacing, letter spacing, text indent and font weight (#310) 2025-02-07 18:23:12 +01:00
Huang Xin adfdb10d8e fix: compatibility fix for some formerly imported corrupted metadata (#307)
* fix: compatibility fix for some formerly imported corrupted metadata

* fix: use font family names of sys fonts
2025-02-07 02:54:29 +01:00
Huang Xin 023ba663e3 fix: stop showing annotator popup when speaking with TTS on Android (#306)
* fix: stop showing annotator popup when speaking with TTS on Android

* chore: get rid of the warning complains of rustc
2025-02-07 01:20:25 +01:00
277 changed files with 16900 additions and 3691 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
---
name: Feature request
about: Share an idea or suggestion
title: 'FR: [a handful of words describing the FR]'
title: 'FR: describing your feature request'
labels: enhancement
assignees: ''
---
**Does your feature request involve difficulty completing a task? Please describe.**
**Does your feature request involve difficulty for you to complete a task? Please describe.**
A clear and concise description of what the problem is. Ex. I think it takes too many steps to [...]
**Describe the solution you'd like**
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
run: cargo fmt --check
- name: Clippy Check
working-directory: apps/readest-app/src-tauri
run: cargo clippy -- -D warnings
run: cargo clippy -p Readest --no-deps -- -D warnings
build_web_app:
runs-on: ubuntu-latest
+67 -8
View File
@@ -56,24 +56,35 @@ jobs:
fail-fast: false
matrix:
config:
- os: ubuntu-latest
release: android
rust_target: aarch64-linux-android,armv7-linux-androideabi,i686-linux-android,x86_64-linux-android
- os: ubuntu-22.04
release: linux
arch: x86_64
rust_target: x86_64-unknown-linux-gnu
- os: ubuntu-22.04-arm
release: linux
arch: aarch64
rust_target: aarch64-unknown-linux-gnu
- os: macos-latest
release: macos
arch: aarch64
rust_target: x86_64-apple-darwin,aarch64-apple-darwin
args: '--target universal-apple-darwin'
- os: windows-latest
release: windows
arch: x86_64
rust_target: x86_64-pc-windows-msvc
args: '--target x86_64-pc-windows-msvc'
- os: windows-latest
release: windows
arch: aarch64
rust_target: aarch64-pc-windows-msvc
args: '--target aarch64-pc-windows-msvc --bundles nsis'
runs-on: ${{ matrix.config.os }}
timeout-minutes: 20
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
@@ -91,6 +102,21 @@ jobs:
node-version: 22
cache: pnpm
- name: setup Java (for Android build only)
if: matrix.config.release == 'android'
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'
- name: setup Android SDK (for Android build only)
if: matrix.config.release == 'android'
uses: android-actions/setup-android@v3
- name: install NDK (for Android build only)
if: matrix.config.release == 'android'
run: sdkmanager "ndk;27.0.11902837"
- name: install dependencies
run: pnpm install
@@ -106,6 +132,12 @@ jobs:
with:
key: ${{ matrix.config.os }}-cargo-${{ hashFiles('Cargo.lock') }}
- name: install dependencies (ubuntu only)
if: contains(matrix.config.os, 'ubuntu') && matrix.config.release != 'android'
run: |
sudo apt-get update
sudo apt-get install -y pkg-config libfontconfig-dev libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils
- name: create .env.local file for Next.js
run: |
echo "NEXT_PUBLIC_POSTHOG_KEY=${{ secrets.NEXT_PUBLIC_POSTHOG_KEY }}" >> .env.local
@@ -113,17 +145,43 @@ jobs:
echo "NEXT_PUBLIC_SUPABASE_URL=${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}" >> .env.local
echo "NEXT_PUBLIC_SUPABASE_ANON_KEY=${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}" >> .env.local
echo "NEXT_PUBLIC_APP_PLATFORM=tauri" >> .env.local
cp .env.local apps/readest-app/.env.local
- name: copy .env.local to apps/readest-app
run: cp .env.local apps/readest-app/.env.local
- name: install dependencies (ubuntu only)
if: matrix.config.os == 'ubuntu-22.04'
- name: build and upload Android apks
if: matrix.config.release == 'android'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NDK_HOME: ${{ env.ANDROID_HOME }}/ndk/27.0.11902837
run: |
sudo apt-get update
sudo apt-get install -y pkg-config libfontconfig-dev libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
cd apps/readest-app/
rm -rf src-tauri/gen/android
pnpm tauri android init
pnpm tauri icon ../../data/icons/readest-book.png
git checkout .
pushd src-tauri/gen/android
echo "keyAlias=${{ secrets.ANDROID_KEY_ALIAS }}" > keystore.properties
echo "password=${{ secrets.ANDROID_KEY_PASSWORD }}" >> keystore.properties
base64 -d <<< "${{ secrets.ANDROID_KEY_BASE64 }}" > $RUNNER_TEMP/keystore.jks
echo "storeFile=$RUNNER_TEMP/keystore.jks" >> keystore.properties
popd
version=${{ needs.get-release.outputs.release_version }}
apk_path=src-tauri/gen/android/app/build/outputs/apk/universal/release
universial_apk=Readest_${version}_universal.apk
arm64_apk=Readest_${version}_arm64.apk
pnpm tauri android build
cp ${apk_path}/app-universal-release.apk $universial_apk
pnpm tauri android build -t aarch64
cp ${apk_path}/app-universal-release.apk $arm64_apk
echo "Uploading $universial_apk to GitHub release"
gh release upload ${{ needs.get-release.outputs.release_tag }} $universial_apk --clobber
echo "Uploading $arm64_apk to GitHub release"
gh release upload ${{ needs.get-release.outputs.release_tag }} $arm64_apk --clobber
- uses: tauri-apps/tauri-action@v0
if: matrix.config.release != 'android'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
@@ -134,6 +192,7 @@ jobs:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
NODE_OPTIONS: '--max-old-space-size=8192'
with:
projectPath: apps/readest-app
releaseId: ${{ needs.get-release.outputs.release_id }}
+2 -2
View File
@@ -1,6 +1,6 @@
[submodule "packages/foliate-js"]
path = packages/foliate-js
url = https://github.com/chrox/foliate-js.git
url = https://github.com/readest/foliate-js.git
[submodule "packages/tauri"]
path = packages/tauri
url = https://github.com/chrox/tauri.git
url = https://github.com/tauri-apps/tauri.git
Generated
+1488 -1432
View File
File diff suppressed because it is too large Load Diff
+16 -1
View File
@@ -1,3 +1,18 @@
[workspace]
members = ["apps/readest-app/src-tauri"]
members = [
"apps/readest-app/src-tauri",
"packages/tauri/crates/tauri",
]
resolver = "2"
[workspace.package]
authors = ["Bilingify LLC"]
homepage = "https://readest.com"
license = "AGPL-3.0"
repository = "https://github.com/readest/readest"
categories = []
edition = "2021"
rust-version = "1.77.2"
[patch.crates-io]
tauri = { path = "packages/tauri/crates/tauri" }
+38
View File
@@ -0,0 +1,38 @@
FROM node:22-slim
ENV PNPM_HOME="/root/.local/share/pnpm"
ENV PATH="${PATH}:${PNPM_HOME}"
RUN npm install --global pnpm
# Install necessary packages
RUN apt update -y && apt install -y --no-install-recommends \
libwebkit2gtk-4.1-dev \
build-essential \
curl \
wget \
file \
libxdo-dev \
libssl-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
ca-certificates \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Install Rust and Cargo
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"
COPY . /app
WORKDIR /app
RUN pnpm install
RUN pnpm --filter @readest/readest-app setup-pdfjs
WORKDIR /app/apps/readest-app
RUN pnpm build-web
ENTRYPOINT ["pnpm", "start-web"]
+32 -13
View File
@@ -5,14 +5,14 @@
<h1>Readest</h1>
<br>
[Readest][link-website] is an open-source ebook reader designed for immersive and deep reading experiences. Built as a modern rewrite of [Foliate](https://github.com/johnfactotum/foliate), it leverages [Next.js 15](https://github.com/vercel/next.js) and [Tauri v2](https://github.com/tauri-apps/tauri) to offer a seamless cross-platform experience on macOS, Windows, Linux and Web, with support for mobile platforms coming soon.
[Readest][link-website] is an open-source ebook reader designed for immersive and deep reading experiences. Built as a modern rewrite of [Foliate](https://github.com/johnfactotum/foliate), it leverages [Next.js 15](https://github.com/vercel/next.js) and [Tauri v2](https://github.com/tauri-apps/tauri) to deliver a smooth, cross-platform experience across macOS, Windows, Linux, Android, iOS, and the Web.
[![Website][badge-website]][link-website]
[![Web App][badge-web-app]][link-web-readest]
[![OS][badge-platforms]][link-website]
<br>
[![][badge-hellogithub]][link-hellogithub]
[![][badge-discord]][link-discord]
<br>
[![AGPL Licence][badge-license]](LICENSE)
[![Latest release][badge-release]][link-gh-releases]
[![Last commit][badge-last-commit]][link-gh-commits]
@@ -32,7 +32,7 @@
<div align="center">
<a href="https://readest.com" target="_blank">
<img src="./data/screenshots/landing_preview.png" alt="Readest Banner" width="100%" />
<img src="./data/screenshots/landing_all_platforms.png" alt="Readest Banner" width="100%" />
</a>
</div>
@@ -42,7 +42,7 @@
| **Feature** | **Description** | **Status** |
| --------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------- |
| **Multi-Format Support** | Support EPUB, MOBI, KF8 (AZW3), FB2, CBZ, PDF (experimental) | ✅ |
| **Multi-Format Support** | Support EPUB, MOBI, KF8 (AZW3), FB2, CBZ, TXT, PDF (experimental) | ✅ |
| **Scroll/Page View Modes** | Switch between scrolling or paginated reading modes. | ✅ |
| **Full-Text Search** | Search across the entire book to find relevant sections. | ✅ |
| **Annotations and Highlighting** | Add highlights, bookmarks, and notes to enhance your reading experience. | ✅ |
@@ -62,9 +62,8 @@
| **Feature** | **Description** | **Priority** |
| ------------------------------- | ------------------------------------------------------------------------------------------ | ------------ |
| **Support iOS and Android** | Expand the APP to work on iOS and Android devices. | 🛠 |
| **Library Management** | Organize, sort, and manage your entire ebook library. | 🛠 |
| **AI-Powered Summarization** | Generate summaries of books or chapters using AI for quick insights. | 🔄 |
| **AI-Powered Summarization** | Generate summaries of books or chapters using AI for quick insights. | 🛠 |
| **Sync with Koreader** | Synchronize reading progress, notes, and bookmarks with [Koreader][link-koreader] devices. | 🔄 |
| **Keyboard Navigation** | Implement vimium-style keybindings for book navigation. | 🔄 |
| **Support OPDS/Calibre** | Integrate OPDS/Calibre to access online libraries and catalogs. | 🔄 |
@@ -81,7 +80,7 @@ Stay tuned for continuous improvements and updates! Contributions and suggestion
![DeepL](./data/screenshots/deepl.png)
![TTS](./data/screenshots/tts_control.png)
![TTS](./data/screenshots/tts_speak_aloud.png)
![Footnote](./data/screenshots/footnote_popover.png)
@@ -95,10 +94,9 @@ Stay tuned for continuous improvements and updates! Contributions and suggestion
The Readest app is available for download! 🥳 🚀
- macOS : Search for "Readest" on the [macOS App Store][link-macos-appstore].
- Windows / Linux: Visit [https://readest.com][link-website] or the [Releases on GitHub][link-gh-releases].
- macOS / iOS / iPadOS : Search for "Readest" on the [App Store][link-appstore], also available on TestFlight for beta test (send your Apple ID to readestapp@gmail.com to request access).
- Windows / Linux / Android: Visit [https://readest.com][link-website] or the [Releases on GitHub][link-gh-releases].
- Web: Visit [https://web.readest.com][link-web-readest].
- iOS / Android: coming soon 👀
## Requirements
@@ -150,19 +148,40 @@ For Windows targets, “Build Tools for Visual Studio 2022” (or a higher editi
### 4. Build for Development
```bash
# Start development for the Tauri app
pnpm tauri dev
# or start development for the Web app
pnpm dev-web
```
For Android:
```bash
# Initialize the Android environment (run once)
pnpm tauri android init
pnpm tauri android dev
# or if you want to dev on a real device
pnpm tauri android dev --host
```
For iOS:
```bash
# Set up the iOS environment (run once)
pnpm tauri ios init
pnpm tauri ios dev
# or if you want to dev on a real device
pnpm tauri ios dev --host
```
### 5. Build for Production
```bash
pnpm tauri build
pnpm tauri android build
pnpm tauri ios build
```
### 6. Setup dev environment with Nix
@@ -186,7 +205,7 @@ Readest is open-source, and contributions are welcome! Feel free to open issues,
<a href="https://github.com/readest/readest/graphs/contributors">
<p align="left">
<img width="300" src="https://contrib.rocks/image?repo=readest/readest" alt="A table of avatars from the project's contributors" />
<img width="500" src="https://contrib.rocks/image?repo=readest/readest" alt="A table of avatars from the project's contributors" />
</p>
</a>
@@ -217,12 +236,12 @@ The following fonts are utilized in this software, either bundled within the app
[badge-web-app]: https://img.shields.io/badge/read%20online-web.readest.com-orange
[badge-license]: https://img.shields.io/github/license/readest/readest?color=teal
[badge-release]: https://img.shields.io/github/release/readest/readest?color=green
[badge-platforms]: https://img.shields.io/badge/platforms-macOS%2C%20Windows%2C%20Linux%2C%20Web%2C%20PWA-green
[badge-platforms]: https://img.shields.io/badge/platforms-macOS%2C%20Windows%2C%20Linux%2C%20Android%2C%20iOS%2C%20Web%2C%20PWA-green
[badge-last-commit]: https://img.shields.io/github/last-commit/readest/readest?color=green
[badge-commit-activity]: https://img.shields.io/github/commit-activity/m/readest/readest
[badge-discord]: https://img.shields.io/discord/1314226120886976544?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=flat-square
[badge-hellogithub]: https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=8a5b6ade2aee461a8bd94e59200682a7&claim_uid=eRLUbPOy2qZtDgw&theme=small
[link-macos-appstore]: https://apps.apple.com/app/apple-store/id6738622779?pt=127463130&ct=github&mt=8
[link-appstore]: https://apps.apple.com/app/apple-store/id6738622779?pt=127463130&ct=github&mt=8
[link-website]: https://readest.com?utm_source=github&utm_medium=referral&utm_campaign=readme
[link-web-readest]: https://web.readest.com
[link-gh-releases]: https://github.com/readest/readest/releases
+22 -2
View File
@@ -4,5 +4,25 @@ NEXT_PUBLIC_POSTHOG_HOST=YOUR_POSTHOG_HOST
NEXT_PUBLIC_SUPABASE_URL=YOUR_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
DEEPL_PRO_API_KEY=YOUR_DEEPL_PRO_API_KEY
DEEPL_FREE_API_KEY=YOUR_DEEPL_FREE_API_KEY
NEXT_PUBLIC_STORAGE_FIXED_QUOTA=1073741824
SUPABASE_ADMIN_KEY=YOUR_SUPABASE_ADMIN_KEY
DEEPL_PRO_API_KEYS=YOUR_DEEPL_PRO_API_KEYS
DEEPL_FREE_API_KEYS=YOUR_DEEPL_FREE_API_KEYS
# r2, s3
NEXT_PUBLIC_OBJECT_STORAGE_TYPE=r2
R2_TOKEN_VALUE=YOUR_R2_TOKEN_VALUE
R2_ACCESS_KEY_ID=YOUR_R2_ACCESS_KEY_ID
R2_SECRET_ACCESS_KEY=YOUR_R2_SECRET_ACCESS_KEY
R2_BUCKET_NAME=YOUR_R2_BUCKET_NAME
R2_ACCOUNT_ID=YOUR_R2_ACCOUNT_ID
R2_REGION=YOUR_R2_REGION
S3_ENDPOINT=PLACE_HOLDER
S3_ACCESS_KEY_ID=PLACE_HOLDER
S3_SECRET_ACCESS_KEY=PLACE_HOLDER
S3_BUCKET_NAME=PLACE_HOLDER
S3_REGION=PLACE_HOLDER
+4
View File
@@ -40,6 +40,10 @@ tauri.*.conf.json
# vercel
.vercel
# open-next
.open-next
.wrangler
# typescript
*.tsbuildinfo
next-env.d.ts
@@ -24,6 +24,7 @@ module.exports = {
'hi',
'id',
'vi',
'ar',
'zh-CN',
'zh-TW',
],
+14 -3
View File
@@ -13,12 +13,23 @@ const nextConfig = {
images: {
unoptimized: true,
},
devIndicators: {
appIsrStatus: false,
},
devIndicators: false,
// Configure assetPrefix or else the server won't properly resolve your assets.
assetPrefix: '',
reactStrictMode: true,
async headers() {
return [
{
source: '/.well-known/apple-app-site-association',
headers: [
{
key: 'Content-Type',
value: 'application/json',
},
],
},
];
},
};
const withPWA = withPWAInit({
+29
View File
@@ -0,0 +1,29 @@
// @ts-nocheck
// default open-next.config.ts file created by @opennextjs/cloudflare
import type { OpenNextConfig } from '@opennextjs/aws/types/open-next.js';
import cache from '@opennextjs/cloudflare/kv-cache';
const config: OpenNextConfig = {
default: {
override: {
wrapper: 'cloudflare-node',
converter: 'edge',
// set `incrementalCache` to "dummy" to disable KV cache
incrementalCache: async () => cache,
tagCache: 'dummy',
queue: 'dummy',
},
},
middleware: {
external: true,
override: {
wrapper: 'cloudflare-edge',
converter: 'edge',
proxyExternalRequest: 'fetch',
},
},
};
export default config;
+29 -17
View File
@@ -1,6 +1,6 @@
{
"name": "@readest/readest-app",
"version": "0.9.9",
"version": "0.9.30",
"private": true,
"scripts": {
"dev": "dotenv -e .env.tauri -- next dev",
@@ -26,7 +26,13 @@
"build-macos-universial": "dotenv -e .env.tauri.local -e .env.apple-nonstore.local -- tauri build -t universal-apple-darwin --bundles dmg",
"build-macos-universial-appstore": "dotenv -e .env.tauri.local -e .env.apple-appstore.local -- tauri build -t universal-apple-darwin --bundles app --config src-tauri/tauri.appstore.conf.json",
"build-macos-universial-appstore-dev": "dotenv -e .env.tauri.local -e .env.apple-appstore-dev.local -- tauri build -t universal-apple-darwin --bundles app --config src-tauri/tauri.appstore-dev.conf.json",
"release-macos-universial-appstore": "dotenv -e .env.tauri.local -e .env.apple-appstore.local -- bash scripts/release-mac-appstore.sh"
"build-ios": "dotenv -e .env.ios-appstore-dev.local -- tauri ios build",
"build-ios-appstore": "dotenv -e .env.ios-appstore.local -- tauri ios build --export-method app-store-connect",
"release-macos-universial-appstore": "dotenv -e .env.tauri.local -e .env.apple-appstore.local -- bash scripts/release-mac-appstore.sh",
"release-ios-appstore": "dotenv -e .env.ios-appstore.local -- bash scripts/release-ios-appstore.sh",
"preview": "NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare && wrangler dev",
"deploy": "NEXT_PUBLIC_APP_PLATFORM=web opennextjs-cloudflare && wrangler deploy",
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.735.0",
@@ -36,19 +42,21 @@
"@supabase/auth-ui-react": "^0.4.7",
"@supabase/auth-ui-shared": "^0.1.8",
"@supabase/supabase-js": "^2.47.7",
"@tauri-apps/api": "2.2.0",
"@tauri-apps/api": "2.4.1",
"@tauri-apps/plugin-cli": "^2.2.0",
"@tauri-apps/plugin-deep-link": "^2.2.0",
"@tauri-apps/plugin-dialog": "^2.2.0",
"@tauri-apps/plugin-fs": "^2.2.0",
"@tauri-apps/plugin-http": "^2.3.0",
"@tauri-apps/plugin-log": "^2.2.1",
"@tauri-apps/plugin-opener": "^2.2.5",
"@tauri-apps/plugin-os": "^2.2.0",
"@tauri-apps/plugin-process": "^2.2.0",
"@tauri-apps/plugin-shell": "~2.2.0",
"@tauri-apps/plugin-updater": "^2.4.0",
"@tauri-apps/plugin-deep-link": "^2.2.1",
"@tauri-apps/plugin-dialog": "^2.2.1",
"@tauri-apps/plugin-fs": "^2.2.1",
"@tauri-apps/plugin-haptics": "^2.2.4",
"@tauri-apps/plugin-http": "^2.4.3",
"@tauri-apps/plugin-log": "^2.3.1",
"@tauri-apps/plugin-opener": "^2.2.6",
"@tauri-apps/plugin-os": "^2.2.1",
"@tauri-apps/plugin-process": "^2.2.1",
"@tauri-apps/plugin-shell": "~2.2.1",
"@tauri-apps/plugin-updater": "^2.7.0",
"@zip.js/zip.js": "^2.7.53",
"aws4fetch": "^1.0.20",
"clsx": "^2.1.1",
"cors": "^2.8.5",
"cssbeautify": "^0.3.1",
@@ -58,9 +66,10 @@
"i18next-http-backend": "^3.0.1",
"js-md5": "^0.8.3",
"jwt-decode": "^4.0.0",
"next": "15.1.6",
"next": "15.2.4",
"posthog-js": "^1.205.0",
"react": "19.0.0",
"react-color": "^2.19.3",
"react-dom": "19.0.0",
"react-i18next": "^15.2.0",
"react-icons": "^5.4.0",
@@ -69,16 +78,18 @@
"zustand": "5.0.1"
},
"devDependencies": {
"@tauri-apps/cli": "2.2.7",
"@opennextjs/cloudflare": "^0.5.12",
"@tauri-apps/cli": "2.4.1",
"@types/cors": "^2.8.17",
"@types/cssbeautify": "^0.3.5",
"@types/node": "^22.10.1",
"@types/react": "18.3.12",
"@types/react-color": "^3.0.13",
"@types/react-dom": "18.3.1",
"@types/tinycolor2": "^1.4.6",
"autoprefixer": "^10.4.20",
"cpx2": "^8.0.0",
"daisyui": "^4.12.23",
"daisyui": "^4.12.24",
"dotenv-cli": "^7.4.4",
"eslint": "^9.16.0",
"eslint-config-next": "15.0.3",
@@ -90,6 +101,7 @@
"postcss-nested": "^7.0.2",
"raw-loader": "^4.0.2",
"tailwindcss": "^3.4.17",
"typescript": "^5.7.2"
"typescript": "^5.7.2",
"wrangler": "^4.4.0"
}
}
@@ -0,0 +1,269 @@
{
"(detected)": "(تم التعرف)",
"About Readest": "حول ريديست",
"Add your notes here...": "أضف ملاحظاتك هنا...",
"Animation": "الرسوم المتحركة",
"Annotate": "إضافة ملاحظة",
"Apply": "تطبيق",
"Are you sure to delete the selected books?": "هل أنت متأكد من رغبتك في حذف الكتب المحددة؟",
"Auto Mode": "الوضع التلقائي",
"Behavior": "السلوك",
"Book": "الكتاب",
"Book Cover": "غلاف الكتاب",
"Bookmark": "علامة مرجعية",
"Cancel": "إلغاء",
"Chapter": "الفصل",
"Cherry": "كرزي",
"Color": "اللون",
"Confirm": "تأكيد",
"Confirm Deletion": "تأكيد الحذف",
"Copied to notebook": "تم النسخ إلى المفكرة",
"Copy": "نسخ",
"Custom CSS": "CSS مخصص",
"Dark Mode": "الوضع المظلم",
"Default": "الافتراضي",
"Default Font": "الخط الافتراضي",
"Default Font Size": "حجم الخط الافتراضي",
"Delete": "حذف",
"Delete Highlight": "حذف التمييز",
"Dictionary": "القاموس",
"Disable Click-to-Flip": "تعطيل التقليب بالنقر",
"Download Readest": "تحميل ريديست",
"Edit": "تحرير",
"Enter your custom CSS here...": "أدخل الـ CSS المخصص هنا...",
"Excerpts": "مقتطفات",
"Failed to import book(s): {{filenames}}": "فشل استيراد الكتاب/الكتب: {{filenames}}",
"Fast": "سريع",
"Font": "الخط",
"Font & Layout": "الخط والتخطيط",
"Font Face": "نوع الخط",
"Font Family": "عائلة الخط",
"Font Size": "حجم الخط",
"Full Justification": "محاذاة كاملة",
"Global Settings": "الإعدادات العامة",
"Go Back": "العودة",
"Go Forward": "التقدم",
"Go Left": "الذهاب لليسار",
"Go Right": "الذهاب لليمين",
"Grass": "عشبي",
"Gray": "رمادي",
"Gruvbox": "چروفبوكس",
"Highlight": "تمييز",
"Horizontal Direction": "الاتجاه الأفقي",
"Hyphenation": "الواصلة",
"Identifier:": "المعرف:",
"Import Books": "استيراد الكتب",
"Language:": "اللغة:",
"Layout": "التخطيط",
"Light Mode": "الوضع الفاتح",
"Loading...": "جارٍ التحميل...",
"Logged in": "تم تسجيل الدخول",
"Logged in as {{userDisplayName}}": "تم تسجيل الدخول باسم {{userDisplayName}}",
"Match Case": "مطابقة حالة الأحرف",
"Match Diacritics": "مطابقة التشكيل",
"Match Whole Words": "مطابقة الكلمات الكاملة",
"Maximum Number of Columns": "العدد الأقصى للأعمدة",
"Minimum Font Size": "الحد الأدنى لحجم الخط",
"Misc": "أخرى",
"Monospace Font": "خط أحادي المسافة (Monospace)",
"More Info": "مزيد من المعلومات",
"Nord": "نورد",
"Notebook": "المفكرة",
"Notes": "الملاحظات",
"Open": "فتح",
"Original Text": "النص الأصلي",
"Page": "الصفحة",
"Paging Animation": "رسوم متحركةعند الانتقال إلى صفحة جديدة",
"Paragraph": "فقرة",
"Parallel Read": "قراءة متوازية",
"Published:": "تاريخ النشر:",
"Publisher:": "الناشر:",
"Reading Progress Synced": "تمت مزامنة تقدم القراءة",
"Reload Page": "إعادة تحميل الصفحة",
"Reveal in File Explorer": "إظهار في مستكشف الملفات",
"Reveal in Finder": "إظهار في Finder",
"Reveal in Folder": "إظهار في المجلد",
"Sans-Serif Font": "خط غير مذيل (Sans-Serif)",
"Save": "حفظ",
"Scrolled Mode": "وضع التمرير",
"Search": "البحث",
"Search Books...": "بحث في الكتب...",
"Search...": "بحث...",
"Select Book": "تحديد الكتاب",
"Select Books": "تحديد الكتب",
"Select Multiple Books": "تحديد عدة كتب",
"Sepia": "بني داكن",
"Serif Font": "خط مذيل (Serif)",
"Show Book Details": "عرض تفاصيل الكتاب",
"Sidebar": "الشريط الجانبي",
"Sign In": "تسجيل الدخول",
"Sign Out": "تسجيل الخروج",
"Sky": "سماوي",
"Slow": "بطيء",
"Solarized": "سولاريزد",
"Speak": "تحدث",
"Subjects:": "المواضيع:",
"System Fonts": "خطوط النظام",
"TTS not supported in this device": "القراءة الصوتية غير مدعومة في هذا الجهاز",
"Theme Color": "لون السمة",
"Theme Mode": "وضع السمة",
"Translate": "ترجمة",
"Translated Text": "النص المترجم",
"Unknown": "غير معروف",
"Untitled": "بدون عنوان",
"Updated:": "تم التحديث:",
"User avatar": "صورة المستخدم",
"Version {{version}}": "الإصدار {{version}}",
"Vertical Direction": "الاتجاه العمودي",
"Welcome to your library. You can import your books here and read them anytime.": "مرحبًا بكم في مكتبتكم. يمكنكم استيراد كتبكم هنا وقراءتها في أي وقت.",
"Wikipedia": "ويكيبيديا",
"Writing Mode": "وضع الكتابة",
"Your Library": "المكتبة الخاصة بك",
"TTS not supported for PDF": "القراءة الصوتية غير مدعومة لملفات PDF",
"Override Book Font": "تجاوز خط الكتاب",
"Vertical Margins (px)": "هوامش عمودية (بكسل)",
"Horizontal Margins (%)": "هوامش أفقية (%)",
"Apply to All Books": "تطبيق على جميع الكتب",
"Apply to This Book": "تطبيق على هذا الكتاب",
"Unable to fetch the translation. Try again later.": "تعذر جلب الترجمة. حاول مرة أخرى لاحقًا.",
"Update Now!": "قم بالتحديث الآن!",
"Update": "تحديث",
"Check Update": "التحقق من التحديث",
"Already the latest version": "الإصدار الحالي هو الإصدار الأحدث بالفعل",
"Book Details": "تفاصيل الكتاب",
"From Local File": "من ملف محلي",
"TOC": "جدول المحتويات",
"Book uploaded: {{title}}": "تم تحميل الكتاب: {{title}}",
"Failed to upload book: {{title}}": "فشل تحميل الكتاب: {{title}}",
"Book downloaded: {{title}}": "تم تنزيل الكتاب: {{title}}",
"Failed to download book: {{title}}": "فشل تنزيل الكتاب: {{title}}",
"Upload Book": "تحميل الكتاب",
"Auto Upload Books to Cloud": "تحميل الكتب تلقائيًا إلى السحابة",
"{{percentage}}% of Cloud Storage Used.": "تم استخدام {{percentage}}% من مساحة التخزين السحابية.",
"Storage": "التخزين",
"Book deleted: {{title}}": "تم حذف الكتاب: {{title}}",
"Failed to delete book: {{title}}": "فشل حذف الكتاب: {{title}}",
"Check Updates on Start": "التحقق من التحديثات عند البدء",
"Insufficient storage quota": "حصة التخزين غير كافية",
"Font Weight": "سمك الخط",
"Line Spacing": "تباعد الأسطر",
"Word Spacing": "تباعد الكلمات",
"Letter Spacing": "تباعد الأحرف",
"Text Indent": "مسافة بادئة للنص",
"Paragraph Margin": "هامش الفقرة",
"Override Book Layout": "تجاوز تخطيط الكتاب",
"Untitled Group": "مجموعة بدون عنوان",
"Group Books": "تجميع الكتب",
"Remove From Group": "إزالة من المجموعة",
"Create New Group": "إنشاء مجموعة جديدة",
"Deselect Book": "إلغاء تحديد الكتاب",
"Download Book": "تنزيل الكتاب",
"Deselect Group": "إلغاء تحديد المجموعة",
"Select Group": "تحديد المجموعة",
"Keep Screen Awake": "إبقاء الشاشة نشطة",
"Email address": "البريد الإلكتروني",
"Your Password": "كلمة المرور",
"Your email address": "البريد الإلكتروني الخاص بك",
"Your password": "كلمة المرور الخاصة بك",
"Sign in": "تسجيل الدخول",
"Signing in...": "يتم الآن تسجيل الدخول...",
"Sign in with {{provider}}": "تسجيل الدخول باستخدام {{provider}}",
"Already have an account? Sign in": "هل لديك حساب بالفعل؟ تسجيل الدخول",
"Create a Password": "إنشاء كلمة مرور",
"Sign up": "إنشاء حساب",
"Signing up...": "يتم الآن إنشاء الحساب...",
"Dont have an account? Sign up": "ليس لديك حساب؟ قم بالتسجيل",
"Check your email for the confirmation link": "تحقق من بريدك الإلكتروني للحصول على رابط التأكيد",
"Signing in ...": "يتم الآن تسجيل الدخول ...",
"Send a magic link email": "إرسال رابط سحري إلى بريدك الإلكتروني",
"Check your email for the magic link": "تحقق من بريدك الإلكتروني للحصول على الرابط السحري",
"Send reset password instructions": "أرسل تعليمات إعادة تعيين كلمة المرور",
"Sending reset instructions ...": "يتم الآن إرسال تعليمات إعادة تعيين كلمة المرور ...",
"Forgot your password?": "نسيت كلمة المرور؟",
"Check your email for the password reset link": "تحقق من بريدك الإلكتروني للحصول على رابط إعادة تعيين كلمة المرور",
"New Password": "كلمة المرور الجديدة",
"Your new password": "أدخل كلمة المرور الجديدة",
"Update password": "تغيير كلمة المرور",
"Updating password ...": "يتم الآن تغيير كلمة المرور ...",
"Your password has been updated": "تم تغيير كلمة المرور الخاصة بك بنجاح",
"Phone number": "رقم الجوال",
"Your phone number": "أدخل رقم الجوال",
"Token": "الرمز",
"Your OTP token": "رمز OTP الذي وصلك",
"Verify token": "التحقق من الرمز",
"Sign in with Google": "تسجيل الدخول عبر Google",
"Sign in with Apple": "تسجيل الدخول عبر Apple",
"Sign in with GitHub": "تسجيل الدخول عبر GitHub",
"Account": "الحساب",
"Cloud Storage": "التخزين السحابي",
"Failed to delete user. Please try again later.": "فشل حذف المستخدم. يرجى المحاولة مرة أخرى لاحقًا.",
"Unlimited Offline/Online Reading": "قراءة غير محدودة بدون اتصال/متصلة بالإنترنت",
"Unlimited Cloud Sync Devices": "أجهزة مزامنة سحابية غير محدودة",
"Essential Text-to-Speech Voices": "أصوات أساسية لتحويل النص إلى كلام",
"DeepL Free Access": "وصول مجاني إلى DeepL",
"Community Support": "دعم المجتمع",
"500 MB Cloud Sync Space": "مساحة مزامنة سحابية 500 ميجابايت",
"Includes All Free Tier Benefits": "يتضمن جميع مزايا الفئة المجانية",
"AI Summaries": "ملخصات الذكاء الاصطناعي",
"AI Translations": "ترجمات الذكاء الاصطناعي",
"Priority Support": "دعم ذو أولوية",
"DeepL Pro Access": "وصول إلى DeepL Pro",
"Expanded Text-to-Speech Voices": "أصوات موسعة لتحويل النص إلى كلام",
"2000 MB Cloud Sync Space": "مساحة مزامنة سحابية 2000 ميجابايت",
"Includes All Plus Tier Benefits": "يتضمن جميع مزايا فئة Plus",
"Unlimited AI Summaries": "ملخصات ذكاء اصطناعي غير محدودة",
"Unlimited AI Translations": "ترجمات ذكاء اصطناعي غير محدودة",
"Unlimited DeepL Pro Access": "وصول غير محدود إلى DeepL Pro",
"Advanced AI Tools": "أدوات ذكاء اصطناعي متقدمة",
"Early Feature Access": "وصول مبكر للميزات",
"10 GB Cloud Sync Space": "مساحة مزامنة سحابية 10 جيجابايت",
"Loading profile...": "جارٍ تحميل الملف الشخصي...",
"Features": "الميزات",
"Delete Account": "حذف الحساب",
"Delete Your Account?": "حذف حسابك؟",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "لا يمكن التراجع عن هذا الإجراء. سيتم حذف جميع بياناتك في السحابة بشكل دائم.",
"Delete Permanently": "حذف نهائي",
"Free Tier": "الفئة المجانية",
"Plus Tier": "فئة Plus",
"Pro Tier": "فئة Pro",
"RTL Direction": "الاتجاه من اليمين إلى اليسار",
"Maximum Column Height": "الارتفاع الأقصى للعمود",
"Maximum Column Width": "العرض الأقصى للعمود",
"Continuous Scroll": "التمرير المستمر",
"Fullscreen": "ملء الشاشة",
"No supported files found. Supported formats: {{formats}}": "لم يتم العثور على ملفات مدعومة. الصيغ المدعومة: {{formats}}",
"Drop to Import Books": "اسحب لاستيراد الكتب",
"Custom": "مخصص",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "العالم مسرح،\nوالناس فيه ممثلون؛\nلهم مخارج ومداخل،\nوالإنسان في حياته يلعب دورًا كثيرًا،\nوأفعاله تمر بسبع مراحل.\n\n— ويليام شكسبير",
"Custom Theme": "سمة مخصصة",
"Theme Name": "اسم السمة",
"Text Color": "لون النص",
"Background Color": "لون الخلفية",
"Preview": "معاينة",
"Contrast": "التباين",
"Sunset": "غروب الشمس",
"Double Border": "حدود مزدوجة",
"Border Color": "لون الحدود",
"Border Frame": "إطار الحدود",
"Show Header": "عرض الرأس",
"Show Footer": "عرض التذييل",
"Small": "صغير",
"Large": "كبير",
"Auto": "تلقائي",
"Language": "اللغة",
"No annotations to export": "لا توجد تعليقات للتصدير",
"Author": "المؤلف",
"Exported from Readest": "تم التصدير من ريديست",
"Highlights & Annotations": "التمييزات والتعليقات",
"Note": "ملاحظة",
"Copied to clipboard": "تم النسخ إلى الحافظة",
"Export Annotations": "تصدير التعليقات",
"Auto Import on File Open": "استيراد تلقائي عند فتح الملف",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "تبديل منطقة التقليب بالنقر",
"No chapters detected.": "لم يتم التعرف على فصول.",
"Failed to parse the EPUB file.": "فشل في تحليل ملف EPUB.",
"This book format is not supported.": "هذا تنسيق الكتاب غير مدعوم.",
"Unable to fetch the translation. Please log in first and try again.": "تعذر جلب الترجمة. يرجى تسجيل الدخول أولاً ثم المحاولة مرة أخرى.",
"Group": "تجميع"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Silbentrennung",
"Identifier:": "Kennung:",
"Import Books": "Bücher importieren",
"Invert Colors in Dark Mode": "Farben im Dunkelmodus invertieren",
"Language:": "Sprache:",
"Layout": "Layout",
"Light Mode": "Hellmodus",
"Line Height": "Zeilenhöhe",
"Loading...": "Wird geladen...",
"Loc. {{currentPage}} / {{totalPage}}": "Pos. {{currentPage}} / {{totalPage}}",
"Logged in": "Angemeldet",
"Logged in as {{userDisplayName}}": "Angemeldet als {{userDisplayName}}",
"Match Case": "Groß-/Kleinschreibung beachten",
"Match Diacritics": "Akzente beachten",
"Match Whole Words": "Ganze Wörter",
"Maximum Block Size": "Maximale Blockgröße",
"Maximum Inline Size": "Maximale Zeilengröße",
"Maximum Number of Columns": "Maximale Spaltenanzahl",
"Minimum Font Size": "Minimale Schriftgröße",
"Misc": "Sonstiges",
@@ -76,7 +71,6 @@
"Notebook": "Notizbuch",
"Notes": "Notizen",
"Open": "Öffnen",
"Open Book": "Buch öffnen",
"Original Text": "Originaltext",
"Page": "Seite",
"Paging Animation": "Blätter-Animation",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Buch gelöscht: {{title}}",
"Failed to delete book: {{title}}": "Fehler beim Löschen des Buches: {{title}}",
"Check Updates on Start": "Aktualisierungen beim Start prüfen",
"Insufficient storage quota": "Unzureichendes Speicherkontingent"
"Insufficient storage quota": "Unzureichendes Speicherkontingent",
"Font Weight": "Schriftgewicht",
"Line Spacing": "Zeilenabstand",
"Word Spacing": "Wortabstand",
"Letter Spacing": "Buchstabenabstand",
"Text Indent": "Texteinzug",
"Paragraph Margin": "Absatzrand",
"Override Book Layout": "Buch-Layout überschreiben",
"Untitled Group": "Unbenannte Gruppe",
"Group Books": "Bücher gruppieren",
"Remove From Group": "Aus Gruppe entfernen",
"Create New Group": "Neue Gruppe erstellen",
"Deselect Book": "Buch abwählen",
"Download Book": "Buch herunterladen",
"Deselect Group": "Gruppe abwählen",
"Select Group": "Gruppe auswählen",
"Keep Screen Awake": "Bildschirm aktiv halten",
"Email address": "E-Mail-Adresse",
"Your Password": "Ihr Passwort",
"Your email address": "Ihre E-Mail-Adresse",
"Your password": "Ihr Passwort",
"Sign in": "Anmelden",
"Signing in...": "Anmeldung...",
"Sign in with {{provider}}": "Mit {{provider}} anmelden",
"Already have an account? Sign in": "Haben Sie bereits ein Konto? Anmelden",
"Create a Password": "Passwort erstellen",
"Sign up": "Registrieren",
"Signing up...": "Registrierung...",
"Dont have an account? Sign up": "Kein Konto? Registrieren",
"Check your email for the confirmation link": "Überprüfen Sie Ihre E-Mails auf den Bestätigungslink",
"Signing in ...": "Anmeldung ...",
"Send a magic link email": "Magic-Link-E-Mail senden",
"Check your email for the magic link": "Überprüfen Sie Ihre E-Mails auf den Magic-Link",
"Send reset password instructions": "Anweisungen zum Zurücksetzen des Passworts senden",
"Sending reset instructions ...": "Sende Anweisungen zum Zurücksetzen ...",
"Forgot your password?": "Passwort vergessen?",
"Check your email for the password reset link": "Überprüfen Sie Ihre E-Mails auf den Link zum Zurücksetzen des Passworts",
"New Password": "Neues Passwort",
"Your new password": "Ihr neues Passwort",
"Update password": "Passwort aktualisieren",
"Updating password ...": "Passwort wird aktualisiert ...",
"Your password has been updated": "Ihr Passwort wurde aktualisiert",
"Phone number": "Telefonnummer",
"Your phone number": "Ihre Telefonnummer",
"Token": "Token",
"Your OTP token": "Ihr OTP-Token",
"Verify token": "Token überprüfen",
"Sign in with Google": "Mit Google anmelden",
"Sign in with Apple": "Mit Apple anmelden",
"Sign in with GitHub": "Mit GitHub anmelden",
"Account": "Konto",
"Cloud Storage": "Cloud-Speicher",
"Failed to delete user. Please try again later.": "Benutzer konnte nicht gelöscht werden. Bitte versuchen Sie es später erneut.",
"Unlimited Offline/Online Reading": "Unbegrenztes Offline/Online Lesen",
"Unlimited Cloud Sync Devices": "Unbegrenzte Cloud-Synchronisierungsgeräte",
"Essential Text-to-Speech Voices": "Grundlegende Text-zu-Sprache-Stimmen",
"DeepL Free Access": "Kostenloser DeepL-Zugang",
"Community Support": "Community-Support",
"500 MB Cloud Sync Space": "500 MB Cloud-Synchronisierungsspeicher",
"Includes All Free Tier Benefits": "Beinhaltet alle Vorteile der kostenlosen Stufe",
"AI Summaries": "KI-Zusammenfassungen",
"AI Translations": "KI-Übersetzungen",
"Priority Support": "Bevorzugter Support",
"DeepL Pro Access": "DeepL Pro-Zugang",
"Expanded Text-to-Speech Voices": "Erweiterte Text-zu-Sprache-Stimmen",
"2000 MB Cloud Sync Space": "2000 MB Cloud-Synchronisierungsspeicher",
"Includes All Plus Tier Benefits": "Beinhaltet alle Vorteile der Plus-Stufe",
"Unlimited AI Summaries": "Unbegrenzte KI-Zusammenfassungen",
"Unlimited AI Translations": "Unbegrenzte KI-Übersetzungen",
"Unlimited DeepL Pro Access": "Unbegrenzter DeepL Pro-Zugang",
"Advanced AI Tools": "Fortgeschrittene KI-Tools",
"Early Feature Access": "Früher Zugang zu neuen Funktionen",
"10 GB Cloud Sync Space": "10 GB Cloud-Synchronisierungsspeicher",
"Loading profile...": "Profil wird geladen...",
"Features": "Funktionen",
"Delete Account": "Konto löschen",
"Delete Your Account?": "Ihr Konto löschen?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Diese Aktion kann nicht rückgängig gemacht werden. Alle Ihre Daten in der Cloud werden dauerhaft gelöscht.",
"Delete Permanently": "Dauerhaft löschen",
"Free Tier": "Kostenlose Stufe",
"Plus Tier": "Plus-Stufe",
"Pro Tier": "Pro-Stufe",
"RTL Direction": "RTL-Richtung",
"Maximum Column Height": "Maximale Spaltenhöhe",
"Maximum Column Width": "Maximale Spaltenbreite",
"Continuous Scroll": "Kontinuierliches Scrollen",
"Fullscreen": "Vollbild",
"No supported files found. Supported formats: {{formats}}": "Keine unterstützten Dateien gefunden. Unterstützte Formate: {{formats}}",
"Drop to Import Books": "Zum Importieren von Büchern ablegen",
"Custom": "Benutzerdefiniert",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Die ganze Welt ist eine Bühne,\nUnd alle Männer und Frauen sind bloß Spieler;\nSie haben ihre Abgänge und ihre Auftritte,\nUnd ein Mann spielt in seinem Leben viele Rollen,\nSeine Taten sind sieben Zeitalter.\n\n— William Shakespeare",
"Custom Theme": "Benutzerdefiniertes Thema",
"Theme Name": "Themenname",
"Text Color": "Textfarbe",
"Background Color": "Hintergrundfarbe",
"Preview": "Vorschau",
"Contrast": "Kontrast",
"Sunset": "Sonnenuntergang",
"Double Border": "Doppelter Rand",
"Border Color": "Randfarbe",
"Border Frame": "Rahmenrand",
"Show Header": "Kopfzeile anzeigen",
"Show Footer": "Fußzeile anzeigen",
"Small": "Klein",
"Large": "Groß",
"Auto": "Automatisch",
"Language": "Sprache",
"No annotations to export": "Keine Anmerkungen zum Exportieren",
"Author": "Autor",
"Exported from Readest": "Exportiert von Readest",
"Highlights & Annotations": "Hervorhebungen & Anmerkungen",
"Note": "Notiz",
"Copied to clipboard": "In die Zwischenablage kopiert",
"Export Annotations": "Anmerkungen exportieren",
"Auto Import on File Open": "Automatischer Import beim Öffnen einer Datei",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Klick-zu-Blättern-Bereich tauschen",
"No chapters detected.": "Keine Kapitel erkannt.",
"Failed to parse the EPUB file.": "Fehler beim Parsen der EPUB-Datei.",
"This book format is not supported.": "Dieses Buchformat wird nicht unterstützt.",
"Unable to fetch the translation. Please log in first and try again.": "Übersetzung konnte nicht abgerufen werden. Bitte zuerst anmelden und erneut versuchen.",
"Group": "Gruppieren"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Συλλαβισμός",
"Identifier:": "Αναγνωριστικό:",
"Import Books": "Εισαγωγή βιβλίων",
"Invert Colors in Dark Mode": "Αντιστροφή χρωμάτων στη σκοτεινή λειτουργία",
"Language:": "Γλώσσα:",
"Layout": "Διάταξη",
"Light Mode": "Φωτεινή λειτουργία",
"Line Height": "Ύψος γραμμής",
"Loading...": "Φόρτωση...",
"Loc. {{currentPage}} / {{totalPage}}": "Θέση {{currentPage}} / {{totalPage}}",
"Logged in": "Συνδεδεμένος",
"Logged in as {{userDisplayName}}": "Συνδεδεμένος ως {{userDisplayName}}",
"Match Case": "Ταίριασμα πεζών-κεφαλαίων",
"Match Diacritics": "Ταίριασμα διακριτικών σημείων",
"Match Whole Words": "Ταίριασμα ολόκληρων λέξεων",
"Maximum Block Size": "Μέγιστο μέγεθος μπλοκ",
"Maximum Inline Size": "Μέγιστο μέγεθος γραμμής",
"Maximum Number of Columns": "Μέγιστος αριθμός στηλών",
"Minimum Font Size": "Ελάχιστο μέγεθος γραμματοσειράς",
"Misc": "Διάφορα",
@@ -76,7 +71,6 @@
"Notebook": "Σημειωματάριο",
"Notes": "Σημειώσεις",
"Open": "Άνοιγμα",
"Open Book": "Άνοιγμα βιβλίου",
"Original Text": "Αρχικό κείμενο",
"Page": "Σελίδα",
"Paging Animation": "Κινούμενα σχέδια σελιδοποίησης",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Το βιβλίο με τίτλο {{title}} διαγράφηκε",
"Failed to delete book: {{title}}": "Αποτυχία διαγραφής βιβλίου: {{title}}",
"Check Updates on Start": "Έλεγχος ενημερώσεων κατά την εκκίνηση",
"Insufficient storage quota": "Ανεπαρκές όριο αποθήκευσης"
"Insufficient storage quota": "Ανεπαρκές όριο αποθήκευσης",
"Font Weight": "Βάρος γραμματοσειράς",
"Line Spacing": "Διάκενο γραμμών",
"Word Spacing": "Διάκενο λέξεων",
"Letter Spacing": "Διάκενο γραμμάτων",
"Text Indent": "Εσοχή κειμένου",
"Paragraph Margin": "Περιθώριο παραγράφου",
"Override Book Layout": "Παράκαμψη διάταξης βιβλίου",
"Untitled Group": "Ομάδα χωρίς τίτλο",
"Group Books": "Ομαδοποίηση βιβλίων",
"Remove From Group": "Αφαίρεση από την ομάδα",
"Create New Group": "Δημιουργία νέας ομάδας",
"Deselect Book": "Αποεπιλογή βιβλίου",
"Download Book": "Λήψη βιβλίου",
"Deselect Group": "Αποεπιλογή ομάδας",
"Select Group": "Επιλογή ομάδας",
"Keep Screen Awake": "Διατήρηση ενεργού οθόνης",
"Email address": "Διεύθυνση email",
"Your Password": "Ο κωδικός σας",
"Your email address": "Η διεύθυνση email σας",
"Your password": "Ο κωδικός πρόσβασής σας",
"Sign in": "Σύνδεση",
"Signing in...": "Σύνδεση...",
"Sign in with {{provider}}": "Σύνδεση με {{provider}}",
"Already have an account? Sign in": "Έχετε ήδη λογαριασμό; Συνδεθείτε",
"Create a Password": "Δημιουργία κωδικού πρόσβασης",
"Sign up": "Εγγραφή",
"Signing up...": "Εγγραφή...",
"Dont have an account? Sign up": "Δεν έχετε λογαριασμό; Εγγραφείτε",
"Check your email for the confirmation link": "Ελέγξτε το email σας για τον σύνδεσμο επιβεβαίωσης",
"Signing in ...": "Σύνδεση ...",
"Send a magic link email": "Αποστολή email με μαγικό σύνδεσμο",
"Check your email for the magic link": "Ελέγξτε το email σας για τον μαγικό σύνδεσμο",
"Send reset password instructions": "Αποστολή οδηγιών επαναφοράς κωδικού πρόσβασης",
"Sending reset instructions ...": "Αποστολή οδηγιών επαναφοράς ...",
"Forgot your password?": "Ξεχάσατε τον κωδικό σας;",
"Check your email for the password reset link": "Ελέγξτε το email σας για τον σύνδεσμο επαναφοράς κωδικού",
"New Password": "Νέος κωδικός πρόσβασης",
"Your new password": "Ο νέος σας κωδικός",
"Update password": "Ενημέρωση κωδικού πρόσβασης",
"Updating password ...": "Ενημέρωση κωδικού ...",
"Your password has been updated": "Ο κωδικός πρόσβασής σας ενημερώθηκε",
"Phone number": "Αριθμός τηλεφώνου",
"Your phone number": "Ο αριθμός τηλεφώνου σας",
"Token": "Κωδικός επαλήθευσης",
"Your OTP token": "Ο κωδικός OTP σας",
"Verify token": "Επαλήθευση κωδικού",
"Sign in with Google": "Σύνδεση με Google",
"Sign in with Apple": "Σύνδεση με Apple",
"Sign in with GitHub": "Σύνδεση με GitHub",
"Account": "Λογαριασμός",
"Cloud Storage": "Αποθηκευτικός χώρος Cloud",
"Failed to delete user. Please try again later.": "Αποτυχία διαγραφής χρήστη. Παρακαλώ δοκιμάστε ξανά αργότερα.",
"Unlimited Offline/Online Reading": "Απεριόριστη ανάγνωση εκτός/εντός σύνδεσης",
"Unlimited Cloud Sync Devices": "Απεριόριστες συσκευές συγχρονισμού Cloud",
"Essential Text-to-Speech Voices": "Βασικές φωνές μετατροπής κειμένου σε ομιλία",
"DeepL Free Access": "Δωρεάν πρόσβαση DeepL",
"Community Support": "Υποστήριξη κοινότητας",
"500 MB Cloud Sync Space": "500 MB χώρος συγχρονισμού Cloud",
"Includes All Free Tier Benefits": "Περιλαμβάνει όλα τα οφέλη της δωρεάν βαθμίδας",
"AI Summaries": "Περιλήψεις AI",
"AI Translations": "Μεταφράσεις AI",
"Priority Support": "Υποστήριξη προτεραιότητας",
"DeepL Pro Access": "Πρόσβαση DeepL Pro",
"Expanded Text-to-Speech Voices": "Διευρυμένες φωνές μετατροπής κειμένου σε ομιλία",
"2000 MB Cloud Sync Space": "2000 MB χώρος συγχρονισμού Cloud",
"Includes All Plus Tier Benefits": "Περιλαμβάνει όλα τα οφέλη της βαθμίδας Plus",
"Unlimited AI Summaries": "Απεριόριστες περιλήψεις AI",
"Unlimited AI Translations": "Απεριόριστες μεταφράσεις AI",
"Unlimited DeepL Pro Access": "Απεριόριστη πρόσβαση DeepL Pro",
"Advanced AI Tools": "Προηγμένα εργαλεία AI",
"Early Feature Access": "Πρώιμη πρόσβαση σε λειτουργίες",
"10 GB Cloud Sync Space": "10 GB χώρος συγχρονισμού Cloud",
"Loading profile...": "Φόρτωση προφίλ...",
"Features": "Χαρακτηριστικά",
"Delete Account": "Διαγραφή λογαριασμού",
"Delete Your Account?": "Διαγραφή του λογαριασμού σας;",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Αυτή η ενέργεια δεν μπορεί να αναιρεθεί. Όλα τα δεδομένα σας στο cloud θα διαγραφούν μόνιμα.",
"Delete Permanently": "Μόνιμη διαγραφή",
"Free Tier": "Δωρεάν βαθμίδα",
"Plus Tier": "Βαθμίδα Plus",
"Pro Tier": "Βαθμίδα Pro",
"RTL Direction": "Κατεύθυνση RTL",
"Maximum Column Height": "Μέγιστο ύψος στήλης",
"Maximum Column Width": "Μέγιστο πλάτος στήλης",
"Continuous Scroll": "Συνεχής κύλιση",
"Fullscreen": "Πλήρης οθόνη",
"No supported files found. Supported formats: {{formats}}": "Δεν βρέθηκαν υποστηριζόμενα αρχεία. Υποστηριζόμενες μορφές: {{formats}}",
"Drop to Import Books": "Ρίξτε για εισαγωγή βιβλίων",
"Custom": "Προσαρμοσμένο",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Όλος ο κόσμος είναι σκηνή,\nΚαι όλοι οι άνδρες και οι γυναίκες απλώς ηθοποιοί·\nΈχουν τις εξόδους και τις εισόδους τους,\nΚαι ένας άνθρωπος στον χρόνο του παίζει πολλούς ρόλους,\nΟι πράξεις του υπάρχουν σε επτά ηλικίες.\n\n— William Shakespeare",
"Custom Theme": "Προσαρμοσμένο θέμα",
"Theme Name": "Όνομα θέματος",
"Text Color": "Χρώμα κειμένου",
"Background Color": "Χρώμα φόντου",
"Preview": "Προεπισκόπηση",
"Contrast": "Αντίθεση",
"Sunset": "Ηλιοβασίλεμα",
"Double Border": "Διπλό περιθώριο",
"Border Color": "Χρώμα περιγράμματος",
"Border Frame": "Πλαίσιο περιγράμματος",
"Show Header": "Εμφάνιση κεφαλίδας",
"Show Footer": "Εμφάνιση υποσέλιδου",
"Small": "Μικρό",
"Large": "Μεγάλο",
"Auto": "Αυτόματο",
"Language": "Γλώσσα",
"No annotations to export": "Δεν υπάρχουν σχολιασμοί για εξαγωγή",
"Author": "Συγγραφέας",
"Exported from Readest": "Εξήχθη από το Readest",
"Highlights & Annotations": "Επισημάνσεις & Σχολιασμοί",
"Note": "Σημείωση",
"Copied to clipboard": "Αντιγράφηκε στο πρόχειρο",
"Export Annotations": "Εξαγωγή σχολιασμών",
"Auto Import on File Open": "Αυτόματη εισαγωγή κατά το άνοιγμα αρχείου",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Ανταλλαγή περιοχής κλικ για γύρισμα σελίδας",
"No chapters detected.": "Δεν εντοπίστηκαν κεφάλαια.",
"Failed to parse the EPUB file.": "Αποτυχία ανάλυσης του αρχείου EPUB.",
"This book format is not supported.": "Αυτή η μορφή βιβλίου δεν υποστηρίζεται.",
"Unable to fetch the translation. Please log in first and try again.": "Αδυναμία λήψης της μετάφρασης. Παρακαλώ συνδεθείτε πρώτα και δοκιμάστε ξανά.",
"Group": "Ομάδα"
}
@@ -1 +1,3 @@
{}
{
"LXGW WenKai GB Screen": "LXGW WenKai"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Guionización",
"Identifier:": "Identificador:",
"Import Books": "Importar libros",
"Invert Colors in Dark Mode": "Invertir colores en modo oscuro",
"Language:": "Idioma:",
"Layout": "Diseño",
"Light Mode": "Modo claro",
"Line Height": "Altura de línea",
"Loading...": "Cargando...",
"Loc. {{currentPage}} / {{totalPage}}": "Pos. {{currentPage}} / {{totalPage}}",
"Logged in": "Sesión iniciada",
"Logged in as {{userDisplayName}}": "Sesión iniciada como {{userDisplayName}}",
"Match Case": "Coincidir mayúsculas y minúsculas",
"Match Diacritics": "Coincidir diacríticos",
"Match Whole Words": "Coincidir palabras completas",
"Maximum Block Size": "Tamaño máximo de bloque",
"Maximum Inline Size": "Tamaño máximo en línea",
"Maximum Number of Columns": "Número máximo de columnas",
"Minimum Font Size": "Tamaño de fuente mínimo",
"Misc": "Varios",
@@ -76,7 +71,6 @@
"Notebook": "Cuaderno",
"Notes": "Notas",
"Open": "Abrir",
"Open Book": "Abrir libro",
"Original Text": "Texto original",
"Page": "Página",
"Paging Animation": "Animación de paginación",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Libro eliminado: {{title}}",
"Failed to delete book: {{title}}": "Error al eliminar libro: {{title}}",
"Check Updates on Start": "Comprobar actualizaciones al iniciar",
"Insufficient storage quota": "Cuota de almacenamiento insuficiente"
"Insufficient storage quota": "Cuota de almacenamiento insuficiente",
"Font Weight": "Peso de la fuente",
"Line Spacing": "Espaciado de línea",
"Word Spacing": "Espaciado de palabras",
"Letter Spacing": "Espaciado de letras",
"Text Indent": "Sangría de texto",
"Paragraph Margin": "Margen de párrafo",
"Override Book Layout": "Sobrescribir diseño del libro",
"Untitled Group": "Grupo sin título",
"Group Books": "Agrupar libros",
"Remove From Group": "Eliminar del grupo",
"Create New Group": "Crear nuevo grupo",
"Deselect Book": "Deseleccionar libro",
"Download Book": "Descargar libro",
"Deselect Group": "Deseleccionar grupo",
"Select Group": "Seleccionar grupo",
"Keep Screen Awake": "Mantener pantalla activa",
"Email address": "Dirección de correo electrónico",
"Your Password": "Tu contraseña",
"Your email address": "Tu dirección de correo electrónico",
"Your password": "Tu contraseña",
"Sign in": "Iniciar sesión",
"Signing in...": "Iniciando sesión...",
"Sign in with {{provider}}": "Iniciar sesión con {{provider}}",
"Already have an account? Sign in": "¿Ya tienes una cuenta? Inicia sesión",
"Create a Password": "Crear una contraseña",
"Sign up": "Registrarse",
"Signing up...": "Registrándose...",
"Dont have an account? Sign up": "¿No tienes una cuenta? Regístrate",
"Check your email for the confirmation link": "Revisa tu correo electrónico para el enlace de confirmación",
"Signing in ...": "Iniciando sesión ...",
"Send a magic link email": "Enviar un enlace mágico por correo",
"Check your email for the magic link": "Revisa tu correo electrónico para el enlace mágico",
"Send reset password instructions": "Enviar instrucciones para restablecer la contraseña",
"Sending reset instructions ...": "Enviando instrucciones de restablecimiento ...",
"Forgot your password?": "¿Olvidaste tu contraseña?",
"Check your email for the password reset link": "Revisa tu correo electrónico para el enlace de restablecimiento de contraseña",
"New Password": "Nueva contraseña",
"Your new password": "Tu nueva contraseña",
"Update password": "Actualizar contraseña",
"Updating password ...": "Actualizando contraseña ...",
"Your password has been updated": "Tu contraseña ha sido actualizada",
"Phone number": "Número de teléfono",
"Your phone number": "Tu número de teléfono",
"Token": "Código de verificación",
"Your OTP token": "Tu código OTP",
"Verify token": "Verificar código",
"Sign in with Google": "Iniciar sesión con Google",
"Sign in with Apple": "Iniciar sesión con Apple",
"Sign in with GitHub": "Iniciar sesión con GitHub",
"Account": "Cuenta",
"Cloud Storage": "Almacenamiento en la nube",
"Failed to delete user. Please try again later.": "Error al eliminar usuario. Por favor, inténtelo de nuevo más tarde.",
"Unlimited Offline/Online Reading": "Lectura sin límites en línea/sin conexión",
"Unlimited Cloud Sync Devices": "Sincronización ilimitada de dispositivos en la nube",
"Essential Text-to-Speech Voices": "Voces esenciales de texto a voz",
"DeepL Free Access": "Acceso gratuito a DeepL",
"Community Support": "Soporte comunitario",
"500 MB Cloud Sync Space": "500 MB de espacio de sincronización en la nube",
"Includes All Free Tier Benefits": "Incluye todos los beneficios del nivel gratuito",
"AI Summaries": "Resúmenes con IA",
"AI Translations": "Traducciones con IA",
"Priority Support": "Soporte prioritario",
"DeepL Pro Access": "Acceso a DeepL Pro",
"Expanded Text-to-Speech Voices": "Voces ampliadas de texto a voz",
"2000 MB Cloud Sync Space": "2000 MB de espacio de sincronización en la nube",
"Includes All Plus Tier Benefits": "Incluye todos los beneficios del nivel Plus",
"Unlimited AI Summaries": "Resúmenes ilimitados con IA",
"Unlimited AI Translations": "Traducciones ilimitadas con IA",
"Unlimited DeepL Pro Access": "Acceso ilimitado a DeepL Pro",
"Advanced AI Tools": "Herramientas avanzadas de IA",
"Early Feature Access": "Acceso anticipado a funciones",
"10 GB Cloud Sync Space": "10 GB de espacio de sincronización en la nube",
"Loading profile...": "Cargando perfil...",
"Features": "Características",
"Delete Account": "Eliminar cuenta",
"Delete Your Account?": "¿Eliminar tu cuenta?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Esta acción no se puede deshacer. Todos tus datos en la nube se eliminarán permanentemente.",
"Delete Permanently": "Eliminar permanentemente",
"Free Tier": "Nivel gratuito",
"Plus Tier": "Nivel Plus",
"Pro Tier": "Nivel Pro",
"RTL Direction": "Dirección RTL",
"Maximum Column Height": "Altura máxima de columna",
"Maximum Column Width": "Ancho máximo de columna",
"Continuous Scroll": "Desplazamiento continuo",
"Fullscreen": "Pantalla completa",
"No supported files found. Supported formats: {{formats}}": "No se encontraron archivos compatibles. Formatos compatibles: {{formats}}",
"Drop to Import Books": "Soltar para importar libros",
"Custom": "Personalizado",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Todo el mundo es un escenario,\nY todos los hombres y mujeres son meros actores;\nTienen sus salidas y sus entradas,\nY un hombre en su tiempo interpreta muchos papeles,\nSus actos son siete edades.\n\n— William Shakespeare",
"Custom Theme": "Tema personalizado",
"Theme Name": "Nombre del tema",
"Text Color": "Color del texto",
"Background Color": "Color de fondo",
"Preview": "Vista previa",
"Contrast": "Contraste",
"Sunset": "Atardecer",
"Double Border": "Doble borde",
"Border Color": "Color del borde",
"Border Frame": "Marco de borde",
"Show Header": "Mostrar encabezado",
"Show Footer": "Mostrar pie de página",
"Small": "Pequeño",
"Large": "Grande",
"Auto": "Automático",
"Language": "Idioma",
"No annotations to export": "No hay anotaciones para exportar",
"Author": "Autor",
"Exported from Readest": "Exportado desde Readest",
"Highlights & Annotations": "Resaltados y anotaciones",
"Note": "Nota",
"Copied to clipboard": "Copiado al portapapeles",
"Export Annotations": "Exportar anotaciones",
"Auto Import on File Open": "Importación automática al abrir archivo",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Intercambiar área de clic para voltear",
"No chapters detected.": "No se detectaron capítulos.",
"Failed to parse the EPUB file.": "Error al analizar el archivo EPUB.",
"This book format is not supported.": "Este formato de libro no es compatible.",
"Unable to fetch the translation. Please log in first and try again.": "No se puede obtener la traducción. Por favor, inicia sesión primero e inténtalo de nuevo.",
"Group": "Grupo"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Césure",
"Identifier:": "Identifiant :",
"Import Books": "Importer des livres",
"Invert Colors in Dark Mode": "Inverser les couleurs en mode sombre",
"Language:": "Langue :",
"Layout": "Mise en page",
"Light Mode": "Mode clair",
"Line Height": "Hauteur de ligne",
"Loading...": "Chargement...",
"Loc. {{currentPage}} / {{totalPage}}": "Pos. {{currentPage}} / {{totalPage}}",
"Logged in": "Connecté",
"Logged in as {{userDisplayName}}": "Connecté en tant que {{userDisplayName}}",
"Match Case": "Respecter la casse",
"Match Diacritics": "Respecter les accents",
"Match Whole Words": "Mots entiers",
"Maximum Block Size": "Taille maximale du bloc",
"Maximum Inline Size": "Taille maximale en ligne",
"Maximum Number of Columns": "Nombre maximal de colonnes",
"Minimum Font Size": "Taille minimale de police",
"Misc": "Divers",
@@ -76,7 +71,6 @@
"Notebook": "Carnet de notes",
"Notes": "Notes",
"Open": "Ouvrir",
"Open Book": "Ouvrir le livre",
"Original Text": "Texte original",
"Page": "Page",
"Paging Animation": "Animation de page",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Livre supprimé : {{title}}",
"Failed to delete book: {{title}}": "Échec de la suppression du livre : {{title}}",
"Check Updates on Start": "Vérifier les mises à jour au démarrage",
"Insufficient storage quota": "Quota de stockage insuffisant"
"Insufficient storage quota": "Quota de stockage insuffisant",
"Font Weight": "Poids de la police",
"Line Spacing": "Interligne",
"Word Spacing": "Espacement des mots",
"Letter Spacing": "Espacement des lettres",
"Text Indent": "Retrait du texte",
"Paragraph Margin": "Marge de paragraphe",
"Override Book Layout": "Remplacer la mise en page du livre",
"Untitled Group": "Groupe sans titre",
"Group Books": "Regrouper les livres",
"Remove From Group": "Retirer du groupe",
"Create New Group": "Créer un nouveau groupe",
"Deselect Book": "Désélectionner le livre",
"Download Book": "Télécharger le livre",
"Deselect Group": "Désélectionner le groupe",
"Select Group": "Sélectionner le groupe",
"Keep Screen Awake": "Maintenir l'écran allumé",
"Email address": "Adresse e-mail",
"Your Password": "Votre mot de passe",
"Your email address": "Votre adresse e-mail",
"Your password": "Votre mot de passe",
"Sign in": "Se connecter",
"Signing in...": "Connexion en cours...",
"Sign in with {{provider}}": "Se connecter avec {{provider}}",
"Already have an account? Sign in": "Vous avez déjà un compte ? Connectez-vous",
"Create a Password": "Créer un mot de passe",
"Sign up": "S'inscrire",
"Signing up...": "Inscription en cours...",
"Dont have an account? Sign up": "Vous n'avez pas de compte ? Inscrivez-vous",
"Check your email for the confirmation link": "Vérifiez votre e-mail pour le lien de confirmation",
"Signing in ...": "Connexion en cours ...",
"Send a magic link email": "Envoyer un e-mail avec un lien magique",
"Check your email for the magic link": "Vérifiez votre e-mail pour le lien magique",
"Send reset password instructions": "Envoyer les instructions de réinitialisation du mot de passe",
"Sending reset instructions ...": "Envoi des instructions de réinitialisation ...",
"Forgot your password?": "Mot de passe oublié ?",
"Check your email for the password reset link": "Vérifiez votre e-mail pour le lien de réinitialisation du mot de passe",
"New Password": "Nouveau mot de passe",
"Your new password": "Votre nouveau mot de passe",
"Update password": "Mettre à jour le mot de passe",
"Updating password ...": "Mise à jour du mot de passe ...",
"Your password has been updated": "Votre mot de passe a été mis à jour",
"Phone number": "Numéro de téléphone",
"Your phone number": "Votre numéro de téléphone",
"Token": "Code de vérification",
"Your OTP token": "Votre code OTP",
"Verify token": "Vérifier le code",
"Sign in with Google": "Se connecter avec Google",
"Sign in with Apple": "Se connecter avec Apple",
"Sign in with GitHub": "Se connecter avec GitHub",
"Account": "Compte",
"Cloud Storage": "Stockage cloud",
"Failed to delete user. Please try again later.": "Échec de la suppression de l'utilisateur. Veuillez réessayer plus tard.",
"Unlimited Offline/Online Reading": "Lecture illimitée hors ligne/en ligne",
"Unlimited Cloud Sync Devices": "Synchronisation cloud sur appareils illimitée",
"Essential Text-to-Speech Voices": "Voix de synthèse vocale essentielles",
"DeepL Free Access": "Accès gratuit à DeepL",
"Community Support": "Support communautaire",
"500 MB Cloud Sync Space": "500 Mo d'espace de synchronisation cloud",
"Includes All Free Tier Benefits": "Inclut tous les avantages du niveau gratuit",
"AI Summaries": "Résumés par IA",
"AI Translations": "Traductions par IA",
"Priority Support": "Support prioritaire",
"DeepL Pro Access": "Accès à DeepL Pro",
"Expanded Text-to-Speech Voices": "Voix de synthèse vocale étendues",
"2000 MB Cloud Sync Space": "2000 Mo d'espace de synchronisation cloud",
"Includes All Plus Tier Benefits": "Inclut tous les avantages du niveau Plus",
"Unlimited AI Summaries": "Résumés par IA illimités",
"Unlimited AI Translations": "Traductions par IA illimitées",
"Unlimited DeepL Pro Access": "Accès illimité à DeepL Pro",
"Advanced AI Tools": "Outils IA avancés",
"Early Feature Access": "Accès anticipé aux fonctionnalités",
"10 GB Cloud Sync Space": "10 Go d'espace de synchronisation cloud",
"Loading profile...": "Chargement du profil...",
"Features": "Fonctionnalités",
"Delete Account": "Supprimer le compte",
"Delete Your Account?": "Supprimer votre compte ?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Cette action est irréversible. Toutes vos données dans le cloud seront définitivement supprimées.",
"Delete Permanently": "Supprimer définitivement",
"Free Tier": "Niveau gratuit",
"Plus Tier": "Niveau Plus",
"Pro Tier": "Niveau Pro",
"RTL Direction": "Direction RTL",
"Maximum Column Height": "Hauteur maximale de colonne",
"Maximum Column Width": "Largeur maximale de colonne",
"Continuous Scroll": "Défilement continu",
"Fullscreen": "Plein écran",
"No supported files found. Supported formats: {{formats}}": "Aucun fichier pris en charge trouvé. Formats pris en charge : {{formats}}",
"Drop to Import Books": "Déposez pour importer des livres",
"Custom": "Personnalisé",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Le monde entier est un théâtre,\nEt tous les hommes et les femmes ne sont que des acteurs ;\nIls ont leurs sorties et leurs entrées,\nEt un homme, dans sa vie, joue de nombreux rôles,\nSes actes étant sept âges.\n\n— William Shakespeare",
"Custom Theme": "Thème personnalisé",
"Theme Name": "Nom du thème",
"Text Color": "Couleur du texte",
"Background Color": "Couleur de fond",
"Preview": "Aperçu",
"Contrast": "Contraste",
"Sunset": "Coucher de soleil",
"Double Border": "Double bordure",
"Border Color": "Couleur de la bordure",
"Border Frame": "Cadre de bordure",
"Show Header": "Afficher l'en-tête",
"Show Footer": "Afficher le pied de page",
"Small": "Petit",
"Large": "Grand",
"Auto": "Automatique",
"Language": "Langue",
"No annotations to export": "Aucune annotation à exporter",
"Author": "Auteur",
"Exported from Readest": "Exporté depuis Readest",
"Highlights & Annotations": "Surlignages et annotations",
"Note": "Note",
"Copied to clipboard": "Copié dans le presse-papiers",
"Export Annotations": "Exporter les annotations",
"Auto Import on File Open": "Importation automatique à l'ouverture du fichier",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Échanger la zone de clic pour tourner",
"No chapters detected.": "Aucun chapitre détecté.",
"Failed to parse the EPUB file.": "Échec de l'analyse du fichier EPUB.",
"This book format is not supported.": "Ce format de livre n'est pas pris en charge.",
"Unable to fetch the translation. Please log in first and try again.": "Impossible de récupérer la traduction. Veuillez d'abord vous connecter et réessayer.",
"Group": "Groupe"
}
@@ -53,20 +53,15 @@
"Hyphenation": "हाइफ़नेशन",
"Identifier:": "पहचानकर्ता:",
"Import Books": "पुस्तकें आयात करें",
"Invert Colors in Dark Mode": "डार्क मोड में रंग उलटें",
"Language:": "भाषा:",
"Layout": "लेआउट",
"Light Mode": "लाइट मोड",
"Line Height": "लाइन हाइट",
"Loading...": "लोड हो रहा है...",
"Loc. {{currentPage}} / {{totalPage}}": "स्थान {{currentPage}} / {{totalPage}}",
"Logged in": "लॉग इन किया",
"Logged in as {{userDisplayName}}": "{{userDisplayName}} के रूप में लॉग इन किया",
"Match Case": "केस मैच करें",
"Match Diacritics": "डायाक्रिटिक्स मैच करें",
"Match Whole Words": "पूरे शब्द मैच करें",
"Maximum Block Size": "अधिकतम ब्लॉक साइज़",
"Maximum Inline Size": "अधिकतम इनलाइन साइज़",
"Maximum Number of Columns": "कॉलम की अधिकतम संख्या",
"Minimum Font Size": "न्यूनतम फ़ॉन्ट साइज़",
"Misc": "विविध",
@@ -76,7 +71,6 @@
"Notebook": "नोटबुक",
"Notes": "नोट्स",
"Open": "खोलें",
"Open Book": "पुस्तक खोलें",
"Original Text": "मूल पाठ",
"Page": "पृष्ठ",
"Paging Animation": "पेजिंग एनीमेशन",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "पुस्तक हटाई गई: {{title}}",
"Failed to delete book: {{title}}": "पुस्तक हटाने में विफल: {{title}}",
"Check Updates on Start": "शुरू में अपडेट जांचें",
"Insufficient storage quota": "अपर्याप्त स्टोरेज कोटा"
"Insufficient storage quota": "अपर्याप्त स्टोरेज कोटा",
"Font Weight": "फ़ॉन्ट वजन",
"Line Spacing": "लाइन स्पेसिंग",
"Word Spacing": "शब्द स्पेसिंग",
"Letter Spacing": "अक्षर स्पेसिंग",
"Text Indent": "टेक्स्ट इंडेंट",
"Paragraph Margin": "पैराग्राफ मार्जिन",
"Override Book Layout": "पुस्तक लेआउट ओवरराइड करें",
"Untitled Group": "अभिनामित समूह",
"Group Books": "समूह पुस्तकें",
"Remove From Group": "समूह से हटाएं",
"Create New Group": "नया समूह बनाएं",
"Deselect Book": "पुस्तक का चयन रद्द करें",
"Download Book": "पुस्तक डाउनलोड करें",
"Deselect Group": "समूह का चयन रद्द करें",
"Select Group": "समूह चुनें",
"Keep Screen Awake": "स्क्रीन जागरूक रखें",
"Email address": "ईमेल पता",
"Your Password": "आपका पासवर्ड",
"Your email address": "आपका ईमेल पता",
"Your password": "आपका पासवर्ड",
"Sign in": "साइन इन करें",
"Signing in...": "साइन इन हो रहा है...",
"Sign in with {{provider}}": "{{provider}} के साथ साइन इन करें",
"Already have an account? Sign in": "पहले से ही एक खाता है? साइन इन करें",
"Create a Password": "पासवर्ड बनाएं",
"Sign up": "साइन अप करें",
"Signing up...": "साइन अप हो रहा है...",
"Dont have an account? Sign up": "कोई खाता नहीं है? साइन अप करें",
"Check your email for the confirmation link": "पुष्टि लिंक के लिए अपना ईमेल जांचें",
"Signing in ...": "साइन इन हो रहा है ...",
"Send a magic link email": "जादू लिंक ईमेल भेजें",
"Check your email for the magic link": "जादू लिंक के लिए अपना ईमेल जांचें",
"Send reset password instructions": "पासवर्ड रीसेट निर्देश भेजें",
"Sending reset instructions ...": "रीसेट निर्देश भेजे जा रहे हैं ...",
"Forgot your password?": "पासवर्ड भूल गए?",
"Check your email for the password reset link": "पासवर्ड रीसेट लिंक के लिए अपना ईमेल जांचें",
"New Password": "नया पासवर्ड",
"Your new password": "आपका नया पासवर्ड",
"Update password": "पासवर्ड अपडेट करें",
"Updating password ...": "पासवर्ड अपडेट किया जा रहा है ...",
"Your password has been updated": "आपका पासवर्ड अपडेट कर दिया गया है",
"Phone number": "फोन नंबर",
"Your phone number": "आपका फोन नंबर",
"Token": "टोकन",
"Your OTP token": "आपका ओटीपी टोकन",
"Verify token": "टोकन सत्यापित करें",
"Sign in with Google": "Google के साथ साइन इन करें",
"Sign in with Apple": "Apple के साथ साइन इन करें",
"Sign in with GitHub": "GitHub के साथ साइन इन करें",
"Account": "खाता",
"Cloud Storage": "क्लाउड स्टोरेज",
"Failed to delete user. Please try again later.": "उपयोगकर्ता को हटाने में विफल। कृपया बाद में पुनः प्रयास करें।",
"Unlimited Offline/Online Reading": "असीमित ऑफलाइन/ऑनलाइन पढ़ना",
"Unlimited Cloud Sync Devices": "असीमित क्लाउड सिंक उपकरण",
"Essential Text-to-Speech Voices": "आवश्यक टेक्स्ट-टू-स्पीच आवाज़ें",
"DeepL Free Access": "DeepL मुफ्त पहुंच",
"Community Support": "सामुदायिक सहायता",
"500 MB Cloud Sync Space": "500 MB क्लाउड सिंक स्पेस",
"Includes All Free Tier Benefits": "सभी फ्री टियर लाभ शामिल हैं",
"AI Summaries": "AI सारांश",
"AI Translations": "AI अनुवाद",
"Priority Support": "प्राथमिकता सहायता",
"DeepL Pro Access": "DeepL प्रो पहुंच",
"Expanded Text-to-Speech Voices": "विस्तारित टेक्स्ट-टू-स्पीच आवाज़ें",
"2000 MB Cloud Sync Space": "2000 MB क्लाउड सिंक स्पेस",
"Includes All Plus Tier Benefits": "सभी प्लस टियर लाभ शामिल हैं",
"Unlimited AI Summaries": "असीमित AI सारांश",
"Unlimited AI Translations": "असीमित AI अनुवाद",
"Unlimited DeepL Pro Access": "असीमित DeepL प्रो पहुंच",
"Advanced AI Tools": "उन्नत AI टूल्स",
"Early Feature Access": "प्रारंभिक फीचर पहुंच",
"10 GB Cloud Sync Space": "10 GB क्लाउड सिंक स्पेस",
"Loading profile...": "प्रोफ़ाइल लोड हो रहा है...",
"Features": "विशेषताएं",
"Delete Account": "खाता हटाएं",
"Delete Your Account?": "अपना खाता हटाएं?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "यह क्रिया पूर्ववत नहीं की जा सकती। क्लाउड में आपका सभी डेटा स्थायी रूप से हटा दिया जाएगा।",
"Delete Permanently": "स्थायी रूप से हटाएं",
"Free Tier": "फ्री टियर",
"Plus Tier": "प्लस टियर",
"Pro Tier": "प्रो टियर",
"RTL Direction": "RTL दिशा",
"Maximum Column Height": "कॉलम की अधिकतम ऊँचाई",
"Maximum Column Width": "कॉलम की अधिकतम चौड़ाई",
"Continuous Scroll": "निरंतर स्क्रॉल",
"Fullscreen": "पूर्णस्क्रीन",
"No supported files found. Supported formats: {{formats}}": "कोई समर्थित फ़ाइलें नहीं मिलीं। समर्थित प्रारूप: {{formats}}",
"Drop to Import Books": "पुस्तकें आयात करने के लिए छोड़ें",
"Custom": "कस्टम",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "पूरी दुनिया एक स्टेज है,\nऔर सभी आदमी और महिलाएँ केवल अभिनेता हैं;\nउनके निकास और प्रवेश होते हैं,\nऔर एक आदमी अपने समय में कई भूमिकाएँ निभाता है,\nउसके कार्य सात युग होते हैं।\n\n— विलियम शेक्सपियर",
"Custom Theme": "कस्टम थीम",
"Theme Name": "थीम का नाम",
"Text Color": "टेक्स्ट रंग",
"Background Color": "पृष्ठभूमि रंग",
"Preview": "पूर्वावलोकन",
"Contrast": "विरोधाभास",
"Sunset": "सनसेट",
"Double Border": "डबल बॉर्डर",
"Border Color": "बॉर्डर रंग",
"Border Frame": "बॉर्डर फ्रेम",
"Show Header": "हेडर दिखाएं",
"Show Footer": "फ़ुटर दिखाएं",
"Small": "छोटा",
"Large": "बड़ा",
"Auto": "स्वचालित",
"Language": "भाषा",
"No annotations to export": "निर्यात करने के लिए कोई टिप्पणियाँ नहीं हैं",
"Author": "लेखक",
"Exported from Readest": "Readest से निर्यात किया गया",
"Highlights & Annotations": "हाइलाइट और टिप्पणियाँ",
"Note": "टिप्पणी",
"Copied to clipboard": "क्लिपबोर्ड पर कॉपी किया गया",
"Export Annotations": "टिप्पणियाँ निर्यात करें",
"Auto Import on File Open": "फ़ाइल खोलने पर स्वचालित आयात",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "क्लिक-टू-फ्लिप क्षेत्र स्वैप करें",
"No chapters detected.": "कोई अध्याय नहीं मिला।",
"Failed to parse the EPUB file.": "EPUB फ़ाइल को पार्स करने में विफल।",
"This book format is not supported.": "यह पुस्तक प्रारूप समर्थित नहीं है।",
"Unable to fetch the translation. Please log in first and try again.": "अनुवाद प्राप्त करने में असमर्थ। कृपया पहले लॉग इन करें और पुनः प्रयास करें।",
"Group": "समूह"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Pemenggalan Kata",
"Identifier:": "Pengenal:",
"Import Books": "Impor Buku",
"Invert Colors in Dark Mode": "Balik Warna di Mode Gelap",
"Language:": "Bahasa:",
"Layout": "Tata Letak",
"Light Mode": "Mode Terang",
"Line Height": "Tinggi Baris",
"Loading...": "Memuat...",
"Loc. {{currentPage}} / {{totalPage}}": "Lok. {{currentPage}} / {{totalPage}}",
"Logged in": "Sudah Masuk",
"Logged in as {{userDisplayName}}": "Masuk sebagai {{userDisplayName}}",
"Match Case": "Cocokkan Huruf Besar/Kecil",
"Match Diacritics": "Cocokkan Diakritik",
"Match Whole Words": "Cocokkan Kata Utuh",
"Maximum Block Size": "Ukuran Blok Maksimum",
"Maximum Inline Size": "Ukuran Sebaris Maksimum",
"Maximum Number of Columns": "Jumlah Kolom Maksimum",
"Minimum Font Size": "Ukuran Font Minimum",
"Misc": "Lain-lain",
@@ -76,7 +71,6 @@
"Notebook": "Buku Catatan",
"Notes": "Catatan",
"Open": "Buka",
"Open Book": "Buka Buku",
"Original Text": "Teks Asli",
"Page": "Halaman",
"Paging Animation": "Animasi Halaman",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Buku dihapus: {{title}}",
"Failed to delete book: {{title}}": "Gagal menghapus buku: {{title}}",
"Check Updates on Start": "Periksa Pembaruan saat Memulai",
"Insufficient storage quota": "Kuota penyimpanan tidak mencukupi"
"Insufficient storage quota": "Kuota penyimpanan tidak mencukupi",
"Font Weight": "Berat Font",
"Line Spacing": "Spasi Baris",
"Word Spacing": "Spasi Kata",
"Letter Spacing": "Spasi Huruf",
"Text Indent": "Indentasi Teks",
"Paragraph Margin": "Margin Paragraf",
"Override Book Layout": "Ganti Tata Letak Buku",
"Untitled Group": "Grup Tanpa Judul",
"Group Books": "Grupkan Buku",
"Remove From Group": "Hapus dari Grup",
"Create New Group": "Buat Grup Baru",
"Deselect Book": "Batalkan Pilihan Buku",
"Download Book": "Unduh Buku",
"Deselect Group": "Batalkan Pilihan Grup",
"Select Group": "Pilih Grup",
"Keep Screen Awake": "Biarkan Layar Tetap Hidup",
"Email address": "Alamat email",
"Your Password": "Kata sandi Anda",
"Your email address": "Alamat email Anda",
"Your password": "Kata sandi Anda",
"Sign in": "Masuk",
"Signing in...": "Sedang masuk...",
"Sign in with {{provider}}": "Masuk dengan {{provider}}",
"Already have an account? Sign in": "Sudah punya akun? Masuk",
"Create a Password": "Buat kata sandi",
"Sign up": "Daftar",
"Signing up...": "Sedang mendaftar...",
"Dont have an account? Sign up": "Belum punya akun? Daftar",
"Check your email for the confirmation link": "Periksa email Anda untuk tautan konfirmasi",
"Signing in ...": "Sedang masuk ...",
"Send a magic link email": "Kirim email tautan ajaib",
"Check your email for the magic link": "Periksa email Anda untuk tautan ajaib",
"Send reset password instructions": "Kirim instruksi reset kata sandi",
"Sending reset instructions ...": "Mengirim instruksi reset ...",
"Forgot your password?": "Lupa kata sandi Anda?",
"Check your email for the password reset link": "Periksa email Anda untuk tautan reset kata sandi",
"New Password": "Kata sandi baru",
"Your new password": "Kata sandi baru Anda",
"Update password": "Perbarui kata sandi",
"Updating password ...": "Memperbarui kata sandi ...",
"Your password has been updated": "Kata sandi Anda telah diperbarui",
"Phone number": "Nomor telepon",
"Your phone number": "Nomor telepon Anda",
"Token": "Token",
"Your OTP token": "Token OTP Anda",
"Verify token": "Verifikasi token",
"Sign in with Google": "Masuk dengan Google",
"Sign in with Apple": "Masuk dengan Apple",
"Sign in with GitHub": "Masuk dengan GitHub",
"Account": "Akun",
"Cloud Storage": "Penyimpanan Cloud",
"Failed to delete user. Please try again later.": "Gagal menghapus pengguna. Silakan coba lagi nanti.",
"Unlimited Offline/Online Reading": "Membaca Offline/Online Tanpa Batas",
"Unlimited Cloud Sync Devices": "Perangkat Sinkronisasi Cloud Tanpa Batas",
"Essential Text-to-Speech Voices": "Suara Text-to-Speech Esensial",
"DeepL Free Access": "Akses DeepL Gratis",
"Community Support": "Dukungan Komunitas",
"500 MB Cloud Sync Space": "Ruang Sinkronisasi Cloud 500 MB",
"Includes All Free Tier Benefits": "Termasuk Semua Manfaat Tingkat Gratis",
"AI Summaries": "Ringkasan AI",
"AI Translations": "Terjemahan AI",
"Priority Support": "Dukungan Prioritas",
"DeepL Pro Access": "Akses DeepL Pro",
"Expanded Text-to-Speech Voices": "Suara Text-to-Speech yang Diperluas",
"2000 MB Cloud Sync Space": "Ruang Sinkronisasi Cloud 2000 MB",
"Includes All Plus Tier Benefits": "Termasuk Semua Manfaat Tingkat Plus",
"Unlimited AI Summaries": "Ringkasan AI Tanpa Batas",
"Unlimited AI Translations": "Terjemahan AI Tanpa Batas",
"Unlimited DeepL Pro Access": "Akses DeepL Pro Tanpa Batas",
"Advanced AI Tools": "Alat AI Lanjutan",
"Early Feature Access": "Akses Fitur Awal",
"10 GB Cloud Sync Space": "Ruang Sinkronisasi Cloud 10 GB",
"Loading profile...": "Memuat profil...",
"Features": "Fitur",
"Delete Account": "Hapus Akun",
"Delete Your Account?": "Hapus Akun Anda?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Tindakan ini tidak dapat dibatalkan. Semua data Anda di cloud akan dihapus secara permanen.",
"Delete Permanently": "Hapus Secara Permanen",
"Free Tier": "Tingkat Gratis",
"Plus Tier": "Tingkat Plus",
"Pro Tier": "Tingkat Pro",
"RTL Direction": "Arah RTL",
"Maximum Column Height": "Tinggi Kolom Maksimum",
"Maximum Column Width": "Lebar Kolom Maksimum",
"Continuous Scroll": "Gulir Terus",
"Fullscreen": "Layar Penuh",
"No supported files found. Supported formats: {{formats}}": "Tidak ada file yang didukung ditemukan. Format yang didukung: {{formats}}",
"Drop to Import Books": "Jatuhkan untuk Mengimpor Buku",
"Custom": "Kustom",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Seluruh dunia adalah panggung,\nDan semua pria dan wanita hanyalah pemain;\nMereka memiliki keluar dan masuk mereka,\nDan seorang pria dalam hidupnya memainkan banyak peran,\nTindakannya ada tujuh zaman.\n\n— William Shakespeare",
"Custom Theme": "Tema Kustom",
"Theme Name": "Nama Tema",
"Text Color": "Warna Teks",
"Background Color": "Warna Latar Belakang",
"Preview": "Pratinjau",
"Contrast": "Kontras",
"Sunset": "Senja",
"Double Border": "Garis Ganda",
"Border Color": "Warna Garis",
"Border Frame": "Bingkai Garis",
"Show Header": "Tampilkan Header",
"Show Footer": "Tampilkan Footer",
"Small": "Kecil",
"Large": "Besar",
"Auto": "Otomatis",
"Language": "Bahasa",
"No annotations to export": "Tidak ada anotasi yang diekspor",
"Author": "Penulis",
"Exported from Readest": "Diekspor dari Readest",
"Highlights & Annotations": "Sorotan & Anotasi",
"Note": "Catatan",
"Copied to clipboard": "Disalin ke papan klip",
"Export Annotations": "Ekspor Anotasi",
"Auto Import on File Open": "Impor Otomatis saat File Dibuka",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Tukar Area Klik untuk Membalik",
"No chapters detected.": "Tidak ada bab yang terdeteksi.",
"Failed to parse the EPUB file.": "Gagal mengurai file EPUB.",
"This book format is not supported.": "Format buku ini tidak didukung.",
"Unable to fetch the translation. Please log in first and try again.": "Tidak dapat mengambil terjemahan. Silakan masuk terlebih dahulu dan coba lagi.",
"Group": "Grup"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Sillabazione",
"Identifier:": "Identificatore:",
"Import Books": "Importa libri",
"Invert Colors in Dark Mode": "Inverti colori in modalità scura",
"Language:": "Lingua:",
"Layout": "Layout",
"Light Mode": "Modalità chiara",
"Line Height": "Altezza riga",
"Loading...": "Caricamento...",
"Loc. {{currentPage}} / {{totalPage}}": "Pos. {{currentPage}} / {{totalPage}}",
"Logged in": "Accesso effettuato",
"Logged in as {{userDisplayName}}": "Accesso effettuato come {{userDisplayName}}",
"Match Case": "Maiuscole/minuscole",
"Match Diacritics": "Corrispondenza diacritici",
"Match Whole Words": "Parole intere",
"Maximum Block Size": "Dimensione massima blocco",
"Maximum Inline Size": "Dimensione massima in linea",
"Maximum Number of Columns": "Numero massimo di colonne",
"Minimum Font Size": "Dimensione minima font",
"Misc": "Varie",
@@ -76,7 +71,6 @@
"Notebook": "Quaderno",
"Notes": "Note",
"Open": "Apri",
"Open Book": "Apri libro",
"Original Text": "Testo originale",
"Page": "Pagina",
"Paging Animation": "Animazione cambio pagina",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Libro eliminato: {{title}}",
"Failed to delete book: {{title}}": "Eliminazione libro non riuscita: {{title}}",
"Check Updates on Start": "Controlla aggiornamenti all'avvio",
"Insufficient storage quota": "Quota di archiviazione insufficiente"
"Insufficient storage quota": "Quota di archiviazione insufficiente",
"Font Weight": "Peso font",
"Line Spacing": "Interlinea",
"Word Spacing": "Spaziatura parole",
"Letter Spacing": "Spaziatura lettere",
"Text Indent": "Rientro testo",
"Paragraph Margin": "Margine paragrafo",
"Override Book Layout": "Sovrascrivi layout libro",
"Untitled Group": "Gruppo senza titolo",
"Group Books": "Raggruppa libri",
"Remove From Group": "Rimuovi dal",
"Create New Group": "Crea nuovo gruppo",
"Deselect Book": "Deseleziona libro",
"Download Book": "Scarica libro",
"Deselect Group": "Deseleziona gruppo",
"Select Group": "Seleziona gruppo",
"Keep Screen Awake": "Mantieni schermo attivo",
"Email address": "Indirizzo email",
"Your Password": "La tua password",
"Your email address": "Il tuo indirizzo email",
"Your password": "La tua password",
"Sign in": "Accedi",
"Signing in...": "Accesso in corso...",
"Sign in with {{provider}}": "Accedi con {{provider}}",
"Already have an account? Sign in": "Hai già un account? Accedi",
"Create a Password": "Crea una password",
"Sign up": "Registrati",
"Signing up...": "Registrazione in corso...",
"Dont have an account? Sign up": "Non hai un account? Registrati",
"Check your email for the confirmation link": "Controlla la tua email per il link di conferma",
"Signing in ...": "Accesso in corso ...",
"Send a magic link email": "Invia un'email con link magico",
"Check your email for the magic link": "Controlla la tua email per il link magico",
"Send reset password instructions": "Invia istruzioni per reimpostare la password",
"Sending reset instructions ...": "Invio istruzioni di reimpostazione ...",
"Forgot your password?": "Hai dimenticato la password?",
"Check your email for the password reset link": "Controlla la tua email per il link di reimpostazione della password",
"New Password": "Nuova password",
"Your new password": "La tua nuova password",
"Update password": "Aggiorna password",
"Updating password ...": "Aggiornamento password ...",
"Your password has been updated": "La tua password è stata aggiornata",
"Phone number": "Numero di telefono",
"Your phone number": "Il tuo numero di telefono",
"Token": "Token",
"Your OTP token": "Il tuo token OTP",
"Verify token": "Verifica token",
"Sign in with Google": "Accedi con Google",
"Sign in with Apple": "Accedi con Apple",
"Sign in with GitHub": "Accedi con GitHub",
"Account": "Account",
"Cloud Storage": "Archiviazione Cloud",
"Failed to delete user. Please try again later.": "Impossibile eliminare l'utente. Riprova più tardi.",
"Unlimited Offline/Online Reading": "Lettura offline/online illimitata",
"Unlimited Cloud Sync Devices": "Sincronizzazione cloud su dispositivi illimitati",
"Essential Text-to-Speech Voices": "Voci essenziali di sintesi vocale",
"DeepL Free Access": "Accesso gratuito a DeepL",
"Community Support": "Supporto della community",
"500 MB Cloud Sync Space": "500 MB di spazio di sincronizzazione cloud",
"Includes All Free Tier Benefits": "Include tutti i vantaggi del piano gratuito",
"AI Summaries": "Riassunti AI",
"AI Translations": "Traduzioni AI",
"Priority Support": "Supporto prioritario",
"DeepL Pro Access": "Accesso a DeepL Pro",
"Expanded Text-to-Speech Voices": "Voci di sintesi vocale ampliate",
"2000 MB Cloud Sync Space": "2000 MB di spazio di sincronizzazione cloud",
"Includes All Plus Tier Benefits": "Include tutti i vantaggi del piano Plus",
"Unlimited AI Summaries": "Riassunti AI illimitati",
"Unlimited AI Translations": "Traduzioni AI illimitate",
"Unlimited DeepL Pro Access": "Accesso illimitato a DeepL Pro",
"Advanced AI Tools": "Strumenti AI avanzati",
"Early Feature Access": "Accesso anticipato alle funzionalità",
"10 GB Cloud Sync Space": "10 GB di spazio di sincronizzazione cloud",
"Loading profile...": "Caricamento profilo...",
"Features": "Funzionalità",
"Delete Account": "Elimina account",
"Delete Your Account?": "Eliminare il tuo account?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Questa azione non può essere annullata. Tutti i tuoi dati nel cloud verranno eliminati definitivamente.",
"Delete Permanently": "Elimina definitivamente",
"Free Tier": "Piano gratuito",
"Plus Tier": "Piano Plus",
"Pro Tier": "Piano Pro",
"RTL Direction": "Direzione RTL",
"Maximum Column Height": "Altezza massima colonna",
"Maximum Column Width": "Larghezza massima colonna",
"Continuous Scroll": "Scorrimento continuo",
"Fullscreen": "Schermo intero",
"No supported files found. Supported formats: {{formats}}": "Nessun file supportato trovato. Formati supportati: {{formats}}",
"Drop to Import Books": "Rilascia per importare libri",
"Custom": "Personalizzato",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Tutto il mondo è un palcoscenico,\nE tutti gli uomini e le donne sono solo attori;\nHanno le loro uscite e le loro entrate,\nE un uomo nella sua vita interpreta molte parti,\nI suoi atti sono sette età.\n\n— William Shakespeare",
"Custom Theme": "Tema personalizzato",
"Theme Name": "Nome tema",
"Text Color": "Colore testo",
"Background Color": "Colore sfondo",
"Preview": "Anteprima",
"Contrast": "Contrasto",
"Sunset": "Tramonto",
"Double Border": "Doppio bordo",
"Border Color": "Colore bordo",
"Border Frame": "Cornice bordo",
"Show Header": "Mostra intestazione",
"Show Footer": "Mostra piè di pagina",
"Small": "Piccolo",
"Large": "Grande",
"Auto": "Automatico",
"Language": "Lingua",
"No annotations to export": "Nessuna annotazione da esportare",
"Author": "Autore",
"Exported from Readest": "Esportato da Readest",
"Highlights & Annotations": "Evidenziazioni e annotazioni",
"Note": "Nota",
"Copied to clipboard": "Copiato negli appunti",
"Export Annotations": "Esporta annotazioni",
"Auto Import on File Open": "Importazione automatica all'apertura del file",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Scambia area click per voltare pagina",
"No chapters detected.": "Nessun capitolo rilevato.",
"Failed to parse the EPUB file.": "Impossibile analizzare il file EPUB.",
"This book format is not supported.": "Questo formato di libro non è supportato.",
"Unable to fetch the translation. Please log in first and try again.": "Impossibile recuperare la traduzione. Accedi prima e riprova.",
"Group": "Gruppo"
}
@@ -53,20 +53,15 @@
"Hyphenation": "ハイフネーション",
"Identifier:": "識別子:",
"Import Books": "書籍をインポート",
"Invert Colors in Dark Mode": "ダークモードで色を反転",
"Language:": "言語:",
"Layout": "レイアウト",
"Light Mode": "ライトモード",
"Line Height": "行間",
"Loading...": "読み込み中...",
"Loc. {{currentPage}} / {{totalPage}}": "位置 {{currentPage}} / {{totalPage}}",
"Logged in": "ログイン済み",
"Logged in as {{userDisplayName}}": "{{userDisplayName}}としてログイン中",
"Match Case": "大文字・小文字を区別",
"Match Diacritics": "アクセント記号を区別",
"Match Whole Words": "単語全体を一致",
"Maximum Block Size": "最大ブロックサイズ",
"Maximum Inline Size": "最大インラインサイズ",
"Maximum Number of Columns": "最大列数",
"Minimum Font Size": "最小フォントサイズ",
"Misc": "その他",
@@ -76,7 +71,6 @@
"Notebook": "ノート",
"Notes": "メモ",
"Open": "開く",
"Open Book": "書籍を開く",
"Original Text": "原文",
"Page": "ページ",
"Paging Animation": "ページめくりアニメーション",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "書籍が削除されました:{{title}}",
"Failed to delete book: {{title}}": "書籍の削除に失敗しました:{{title}}",
"Check Updates on Start": "開始時に更新を確認",
"Insufficient storage quota": "ストレージクォータが不足しています"
"Insufficient storage quota": "ストレージクォータが不足しています",
"Font Weight": "フォントウェイト",
"Line Spacing": "行間",
"Word Spacing": "単語間隔",
"Letter Spacing": "文字間隔",
"Text Indent": "テキストインデント",
"Paragraph Margin": "段落マージン",
"Override Book Layout": "書籍のレイアウトを上書き",
"Untitled Group": "無題のグループ",
"Group Books": "書籍をグループ化",
"Remove From Group": "グループから削除",
"Create New Group": "新しいグループを作成",
"Deselect Book": "書籍の選択を解除",
"Download Book": "書籍をダウンロード",
"Deselect Group": "グループの選択を解除",
"Select Group": "グループを選択",
"Keep Screen Awake": "画面をオンのままにする",
"Email address": "メールアドレス",
"Your Password": "あなたのパスワード",
"Your email address": "あなたのメールアドレス",
"Your password": "あなたのパスワード",
"Sign in": "サインイン",
"Signing in...": "サインイン中...",
"Sign in with {{provider}}": "{{provider}}でサインイン",
"Already have an account? Sign in": "すでにアカウントがありますか? サインイン",
"Create a Password": "パスワードを作成",
"Sign up": "サインアップ",
"Signing up...": "サインアップ中...",
"Dont have an account? Sign up": "アカウントをお持ちでないですか? サインアップ",
"Check your email for the confirmation link": "確認リンクのためにメールを確認してください",
"Signing in ...": "サインイン中 ...",
"Send a magic link email": "マジックリンクメールを送信",
"Check your email for the magic link": "マジックリンクのためにメールを確認してください",
"Send reset password instructions": "パスワードリセットの指示を送信",
"Sending reset instructions ...": "リセット指示を送信中 ...",
"Forgot your password?": "パスワードを忘れましたか?",
"Check your email for the password reset link": "パスワードリセットリンクのためにメールを確認してください",
"New Password": "新しいパスワード",
"Your new password": "あなたの新しいパスワード",
"Update password": "パスワードを更新",
"Updating password ...": "パスワード更新中 ...",
"Your password has been updated": "あなたのパスワードは更新されました",
"Phone number": "電話番号",
"Your phone number": "あなたの電話番号",
"Token": "トークン",
"Your OTP token": "あなたのOTPトークン",
"Verify token": "トークンを確認",
"Sign in with Google": "Googleでサインイン",
"Sign in with Apple": "Appleでサインイン",
"Sign in with GitHub": "GitHubでサインイン",
"Account": "アカウント",
"Cloud Storage": "クラウドストレージ",
"Failed to delete user. Please try again later.": "ユーザーの削除に失敗しました。後ほど再試行してください。",
"Unlimited Offline/Online Reading": "無制限のオフライン/オンライン読書",
"Unlimited Cloud Sync Devices": "無制限のクラウド同期デバイス",
"Essential Text-to-Speech Voices": "基本的な音声合成ボイス",
"DeepL Free Access": "DeepL無料アクセス",
"Community Support": "コミュニティサポート",
"500 MB Cloud Sync Space": "500 MBのクラウド同期スペース",
"Includes All Free Tier Benefits": "無料プランの全特典を含む",
"AI Summaries": "AI要約",
"AI Translations": "AI翻訳",
"Priority Support": "優先サポート",
"DeepL Pro Access": "DeepL Proアクセス",
"Expanded Text-to-Speech Voices": "拡張された音声合成ボイス",
"2000 MB Cloud Sync Space": "2000 MBのクラウド同期スペース",
"Includes All Plus Tier Benefits": "Plusプランの全特典を含む",
"Unlimited AI Summaries": "無制限のAI要約",
"Unlimited AI Translations": "無制限のAI翻訳",
"Unlimited DeepL Pro Access": "無制限のDeepL Proアクセス",
"Advanced AI Tools": "高度なAIツール",
"Early Feature Access": "新機能への早期アクセス",
"10 GB Cloud Sync Space": "10 GBのクラウド同期スペース",
"Loading profile...": "プロフィール読み込み中...",
"Features": "機能",
"Delete Account": "アカウント削除",
"Delete Your Account?": "アカウントを削除しますか?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "この操作は元に戻せません。クラウド上のすべてのデータが完全に削除されます。",
"Delete Permanently": "完全に削除",
"Free Tier": "無料プラン",
"Plus Tier": "Plusプラン",
"Pro Tier": "Proプラン",
"RTL Direction": "RTL方向",
"Maximum Column Height": "最大列高",
"Maximum Column Width": "最大列幅",
"Continuous Scroll": "連続スクロール",
"Fullscreen": "全画面",
"No supported files found. Supported formats: {{formats}}": "サポートされているファイルが見つかりません。サポートされている形式:{{formats}}",
"Drop to Import Books": "書籍をインポートするにはドロップ",
"Custom": "カスタム",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "全世界は舞台であり、\nそしてすべての男性と女性は単なる役者です。\n彼らは出入り口を持っており、\nそして一人の男性は時に多くの役を演じます。\n彼の行為は七つの時代です。\n\n— ウィリアム・シェイクスピア",
"Custom Theme": "カスタムテーマ",
"Theme Name": "テーマ名",
"Text Color": "テキストカラー",
"Background Color": "背景色",
"Preview": "プレビュー",
"Contrast": "コントラスト",
"Sunset": "サンセット",
"Double Border": "二重枠",
"Border Color": "ボーダーカラー",
"Border Frame": "ボーダーフレーム",
"Show Header": "ヘッダーを表示",
"Show Footer": "フッターを表示",
"Small": "小",
"Large": "大",
"Auto": "自動",
"Language": "言語",
"No annotations to export": "エクスポートする注釈はありません",
"Author": "著者",
"Exported from Readest": "Readestからエクスポート",
"Highlights & Annotations": "ハイライトと注釈",
"Note": "メモ",
"Copied to clipboard": "クリップボードにコピー",
"Export Annotations": "注釈をエクスポート",
"Auto Import on File Open": "ファイルを開くと自動インポート",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "クリックめくりエリアを入れ替え",
"No chapters detected.": "章が検出されません。",
"Failed to parse the EPUB file.": "EPUBファイルの解析に失敗しました。",
"This book format is not supported.": "この書籍形式はサポートされていません。",
"Unable to fetch the translation. Please log in first and try again.": "翻訳を取得できません。まずログインして再試行してください。",
"Group": "グループ"
}
@@ -53,20 +53,15 @@
"Hyphenation": "하이픈 넣기",
"Identifier:": "식별자:",
"Import Books": "책 가져오기",
"Invert Colors in Dark Mode": "다크 모드에서 색상 반전",
"Language:": "언어:",
"Layout": "레이아웃",
"Light Mode": "라이트 모드",
"Line Height": "줄 간격",
"Loading...": "로딩 중...",
"Loc. {{currentPage}} / {{totalPage}}": "위치 {{currentPage}} / {{totalPage}}",
"Logged in": "로그인됨",
"Logged in as {{userDisplayName}}": "{{userDisplayName}}(으)로 로그인됨",
"Match Case": "대소문자 구분",
"Match Diacritics": "발음 구별 부호 구분",
"Match Whole Words": "전체 단어 일치",
"Maximum Block Size": "최대 블록 크기",
"Maximum Inline Size": "최대 인라인 크기",
"Maximum Number of Columns": "최대 열 수",
"Minimum Font Size": "최소 글꼴 크기",
"Misc": "기타",
@@ -76,7 +71,6 @@
"Notebook": "노트북",
"Notes": "메모",
"Open": "열기",
"Open Book": "책 열기",
"Original Text": "원본 텍스트",
"Page": "페이지",
"Paging Animation": "페이지 넘김 애니메이션",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "책 삭제됨: {{title}}",
"Failed to delete book: {{title}}": "책 삭제 실패: {{title}}",
"Check Updates on Start": "시작 시 업데이트 확인",
"Insufficient storage quota": "저장소 할당량 부족"
"Insufficient storage quota": "저장소 할당량 부족",
"Font Weight": "글꼴 두께",
"Line Spacing": "줄 간격",
"Word Spacing": "단어 간격",
"Letter Spacing": "글자 간격",
"Text Indent": "들여쓰기",
"Paragraph Margin": "단락 여백",
"Override Book Layout": "책 레이아웃 덮어쓰기",
"Untitled Group": "제목 없는 그룹",
"Group Books": "책 그룹화",
"Remove From Group": "그룹에서 제거",
"Create New Group": "새 그룹 만들기",
"Deselect Book": "책 선택 해제",
"Download Book": "책 다운로드",
"Deselect Group": "그룹 선택 해제",
"Select Group": "그룹 선택",
"Keep Screen Awake": "화면 켜짐 유지",
"Email address": "이메일 주소",
"Your Password": "비밀번호",
"Your email address": "당신의 이메일 주소",
"Your password": "당신의 비밀번호",
"Sign in": "로그인",
"Signing in...": "로그인 중...",
"Sign in with {{provider}}": "{{provider}}로 로그인",
"Already have an account? Sign in": "이미 계정이 있습니까? 로그인",
"Create a Password": "비밀번호 만들기",
"Sign up": "회원가입",
"Signing up...": "회원가입 중...",
"Dont have an account? Sign up": "계정이 없습니까? 회원가입",
"Check your email for the confirmation link": "확인 링크를 위해 이메일을 확인하세요",
"Signing in ...": "로그인 중 ...",
"Send a magic link email": "마법의 링크 이메일 보내기",
"Check your email for the magic link": "마법의 링크를 위해 이메일을 확인하세요",
"Send reset password instructions": "비밀번호 재설정 지침 보내기",
"Sending reset instructions ...": "재설정 지침 보내는 중 ...",
"Forgot your password?": "비밀번호를 잊으셨나요?",
"Check your email for the password reset link": "비밀번호 재설정 링크를 위해 이메일을 확인하세요",
"New Password": "새로운 비밀번호",
"Your new password": "당신의 새로운 비밀번호",
"Update password": "비밀번호 업데이트",
"Updating password ...": "비밀번호 업데이트 중 ...",
"Your password has been updated": "비밀번호가 업데이트되었습니다",
"Phone number": "전화번호",
"Your phone number": "당신의 전화번호",
"Token": "토큰",
"Your OTP token": "당신의 OTP 토큰",
"Verify token": "토큰 확인",
"Sign in with Google": "Google로 로그인",
"Sign in with Apple": "Apple로 로그인",
"Sign in with GitHub": "GitHub로 로그인",
"Account": "계정",
"Cloud Storage": "클라우드 스토리지",
"Failed to delete user. Please try again later.": "사용자 삭제에 실패했습니다. 나중에 다시 시도해 주세요.",
"Unlimited Offline/Online Reading": "무제한 오프라인/온라인 읽기",
"Unlimited Cloud Sync Devices": "무제한 클라우드 동기화 기기",
"Essential Text-to-Speech Voices": "필수 텍스트 음성 변환 목소리",
"DeepL Free Access": "DeepL 무료 접근",
"Community Support": "커뮤니티 지원",
"500 MB Cloud Sync Space": "500 MB 클라우드 동기화 공간",
"Includes All Free Tier Benefits": "무료 등급의 모든 혜택 포함",
"AI Summaries": "AI 요약",
"AI Translations": "AI 번역",
"Priority Support": "우선 지원",
"DeepL Pro Access": "DeepL 프로 접근",
"Expanded Text-to-Speech Voices": "확장된 텍스트 음성 변환 목소리",
"2000 MB Cloud Sync Space": "2000 MB 클라우드 동기화 공간",
"Includes All Plus Tier Benefits": "플러스 등급의 모든 혜택 포함",
"Unlimited AI Summaries": "무제한 AI 요약",
"Unlimited AI Translations": "무제한 AI 번역",
"Unlimited DeepL Pro Access": "무제한 DeepL 프로 접근",
"Advanced AI Tools": "고급 AI 도구",
"Early Feature Access": "신기능 조기 접근",
"10 GB Cloud Sync Space": "10 GB 클라우드 동기화 공간",
"Loading profile...": "프로필 로딩 중...",
"Features": "기능",
"Delete Account": "계정 삭제",
"Delete Your Account?": "계정을 삭제하시겠습니까?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "이 작업은 취소할 수 없습니다. 클라우드에 있는 모든 데이터가 영구적으로 삭제됩니다.",
"Delete Permanently": "영구 삭제",
"Free Tier": "무료 등급",
"Plus Tier": "플러스 등급",
"Pro Tier": "프로 등급",
"RTL Direction": "RTL 방향",
"Maximum Column Height": "최대 열 높이",
"Maximum Column Width": "최대 열 너비",
"Continuous Scroll": "연속 스크롤",
"Fullscreen": "전체 화면",
"No supported files found. Supported formats: {{formats}}": "지원되는 파일이 없습니다. 지원되는 형식: {{formats}}",
"Drop to Import Books": "책 가져오기 위해 드롭",
"Custom": "사용자 정의",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "세상은 무대이며,\n그리고 모든 남자와 여자는 단지 배우일 뿐입니다;\n그들은 나가는 곳과 들어오는 곳이 있으며,\n그리고 한 남자는 그의 시간에 많은 역할을 합니다,\n그의 행동은 일곱 시대입니다.\n\n— 윌리엄 셰익스피어",
"Custom Theme": "사용자 정의 테마",
"Theme Name": "테마 이름",
"Text Color": "텍스트 색상",
"Background Color": "배경 색상",
"Preview": "미리보기",
"Contrast": "대비",
"Sunset": "일몰",
"Double Border": "이중 테두리",
"Border Color": "테두리 색상",
"Border Frame": "테두리 프레임",
"Show Header": "헤더 표시",
"Show Footer": "푸터 표시",
"Small": "작음",
"Large": "큼",
"Auto": "자동",
"Language": "언어",
"No annotations to export": "내보낼 주석이 없습니다",
"Author": "저자",
"Exported from Readest": "Readest에서 내보냄",
"Highlights & Annotations": "하이라이트 및 주석",
"Note": "노트",
"Copied to clipboard": "클립보드에 복사",
"Export Annotations": "주석 내보내기",
"Auto Import on File Open": "파일 열 때 자동 가져오기",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "클릭-뒤집기 영역 교환",
"No chapters detected.": "장 발견되지 않음.",
"Failed to parse the EPUB file.": "EPUB 파일 구문 분석 실패.",
"This book format is not supported.": "이 책 형식은 지원되지 않습니다.",
"Unable to fetch the translation. Please log in first and try again.": "번역을 가져올 수 없습니다. 먼저 로그인하고 다시 시도하세요.",
"Group": "그룹"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Dzielenie wyrazów",
"Identifier:": "Identyfikator:",
"Import Books": "Importuj książki",
"Invert Colors in Dark Mode": "Odwróć kolory w trybie ciemnym",
"Language:": "Język:",
"Layout": "Układ",
"Light Mode": "Tryb jasny",
"Line Height": "Wysokość linii",
"Loading...": "Ładowanie...",
"Loc. {{currentPage}} / {{totalPage}}": "Poz. {{currentPage}} / {{totalPage}}",
"Logged in": "Zalogowano",
"Logged in as {{userDisplayName}}": "Zalogowano jako {{userDisplayName}}",
"Match Case": "Uwzględnij wielkość liter",
"Match Diacritics": "Uwzględnij znaki diakrytyczne",
"Match Whole Words": "Uwzględnij całe słowa",
"Maximum Block Size": "Maksymalny rozmiar bloku",
"Maximum Inline Size": "Maksymalny rozmiar linii",
"Maximum Number of Columns": "Maksymalna liczba kolumn",
"Minimum Font Size": "Minimalny rozmiar czcionki",
"Misc": "Różne",
@@ -76,7 +71,6 @@
"Notebook": "Notatnik",
"Notes": "Notatki",
"Open": "Otwórz",
"Open Book": "Otwórz książkę",
"Original Text": "Tekst oryginalny",
"Page": "Strona",
"Paging Animation": "Animacja przewracania stron",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Książka usunięta: {{title}}",
"Failed to delete book: {{title}}": "Nie udało się usunąć książki: {{title}}",
"Check Updates on Start": "Sprawdź aktualizacje przy starcie",
"Insufficient storage quota": "Niewystarczająca kwota przechowywania"
"Insufficient storage quota": "Niewystarczająca kwota przechowywania",
"Font Weight": "Grubość czcionki",
"Line Spacing": "Interlinia",
"Word Spacing": "Odstęp między wyrazami",
"Letter Spacing": "Odstęp między literami",
"Text Indent": "Wcięcie tekstu",
"Paragraph Margin": "Margines akapitu",
"Override Book Layout": "Nadpisz układ książki",
"Untitled Group": "Grupa bez tytułu",
"Group Books": "Grupuj książki",
"Remove From Group": "Usuń z grupy",
"Create New Group": "Utwórz nową grupę",
"Deselect Book": "Odznacz książkę",
"Download Book": "Pobierz książkę",
"Deselect Group": "Odznacz grupę",
"Select Group": "Wybierz grupę",
"Keep Screen Awake": "Nie wygaszaj ekranu",
"Email address": "Adres email",
"Your Password": "Twoje hasło",
"Your email address": "Twój adres email",
"Your password": "Twoje hasło",
"Sign in": "Zaloguj się",
"Signing in...": "Logowanie...",
"Sign in with {{provider}}": "Zaloguj się za pomocą {{provider}}",
"Already have an account? Sign in": "Masz już konto? Zaloguj się",
"Create a Password": "Utwórz hasło",
"Sign up": "Zarejestruj się",
"Signing up...": "Rejestracja...",
"Dont have an account? Sign up": "Nie masz konta? Zarejestruj się",
"Check your email for the confirmation link": "Sprawdź swój email, aby uzyskać link potwierdzający",
"Signing in ...": "Logowanie ...",
"Send a magic link email": "Wyślij link magiczny na email",
"Check your email for the magic link": "Sprawdź swój email, aby uzyskać link magiczny",
"Send reset password instructions": "Wyślij instrukcje resetowania hasła",
"Sending reset instructions ...": "Wysyłanie instrukcji resetowania hasła ...",
"Forgot your password?": "Zapomniałeś hasła?",
"Check your email for the password reset link": "Sprawdź swój email, aby uzyskać link resetujący hasło",
"New Password": "Nowe hasło",
"Your new password": "Twoje nowe hasło",
"Update password": "Zaktualizuj hasło",
"Updating password ...": "Aktualizacja hasła ...",
"Your password has been updated": "Twoje hasło zostało zaktualizowane",
"Phone number": "Numer telefonu",
"Your phone number": "Twój numer telefonu",
"Token": "Token",
"Your OTP token": "Twój OTP token",
"Verify token": "Weryfikacja tokena",
"Sign in with Google": "Zaloguj się za pomocą Google",
"Sign in with Apple": "Zaloguj się za pomocą Apple",
"Sign in with GitHub": "Zaloguj się za pomocą GitHub",
"Account": "Konto",
"Cloud Storage": "Przestrzeń w chmurze",
"Failed to delete user. Please try again later.": "Nie udało się usunąć użytkownika. Spróbuj ponownie później.",
"Unlimited Offline/Online Reading": "Nieograniczone czytanie offline/online",
"Unlimited Cloud Sync Devices": "Nieograniczona liczba urządzeń synchronizowanych w chmurze",
"Essential Text-to-Speech Voices": "Podstawowe głosy zamiany tekstu na mowę",
"DeepL Free Access": "Darmowy dostęp do DeepL",
"Community Support": "Wsparcie społeczności",
"500 MB Cloud Sync Space": "500 MB przestrzeni synchronizacji w chmurze",
"Includes All Free Tier Benefits": "Zawiera wszystkie korzyści darmowego planu",
"AI Summaries": "Podsumowania AI",
"AI Translations": "Tłumaczenia AI",
"Priority Support": "Priorytetowe wsparcie",
"DeepL Pro Access": "Dostęp do DeepL Pro",
"Expanded Text-to-Speech Voices": "Rozszerzone głosy zamiany tekstu na mowę",
"2000 MB Cloud Sync Space": "2000 MB przestrzeni synchronizacji w chmurze",
"Includes All Plus Tier Benefits": "Zawiera wszystkie korzyści planu Plus",
"Unlimited AI Summaries": "Nieograniczone podsumowania AI",
"Unlimited AI Translations": "Nieograniczone tłumaczenia AI",
"Unlimited DeepL Pro Access": "Nieograniczony dostęp do DeepL Pro",
"Advanced AI Tools": "Zaawansowane narzędzia AI",
"Early Feature Access": "Wczesny dostęp do nowych funkcji",
"10 GB Cloud Sync Space": "10 GB przestrzeni synchronizacji w chmurze",
"Loading profile...": "Ładowanie profilu...",
"Features": "Funkcje",
"Delete Account": "Usuń konto",
"Delete Your Account?": "Usunąć Twoje konto?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Tej operacji nie można cofnąć. Wszystkie Twoje dane w chmurze zostaną trwale usunięte.",
"Delete Permanently": "Usuń trwale",
"Free Tier": "Plan darmowy",
"Plus Tier": "Plan Plus",
"Pro Tier": "Plan Pro",
"RTL Direction": "Kierunek RTL",
"Maximum Column Height": "Maksymalna wysokość kolumny",
"Maximum Column Width": "Maksymalna szerokość kolumny",
"Continuous Scroll": "Przewijanie ciągłe",
"Fullscreen": "Pełny ekran",
"No supported files found. Supported formats: {{formats}}": "Nie znaleziono obsługiwanych plików. Obsługiwane formaty: {{formats}}",
"Drop to Import Books": "Upuść, aby zaimportować książki",
"Custom": "Niestandardowy",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Cały świat jest sceną,\nA wszyscy mężczyźni i kobiety są tylko aktorami;\nMają swoje wyjścia i wejścia,\nI jeden człowiek w swoim czasie gra wiele ról,\nJego czyny to siedem wieków.\n\n— William Shakespeare",
"Custom Theme": "Niestandardowy motyw",
"Theme Name": "Nazwa motywu",
"Text Color": "Kolor tekstu",
"Background Color": "Kolor tła",
"Preview": "Podgląd",
"Contrast": "Kontrast",
"Sunset": "Zachód słońca",
"Double Border": "Podwójna ramka",
"Border Color": "Kolor ramki",
"Border Frame": "Ramka",
"Show Header": "Pokaż nagłówek",
"Show Footer": "Pokaż stopkę",
"Small": "Mały",
"Large": "Duży",
"Auto": "Automatyczny",
"Language": "Język",
"No annotations to export": "Brak adnotacji do eksportu",
"Author": "Autor",
"Exported from Readest": "Eksportowane z Readest",
"Highlights & Annotations": "Zaznaczenia i adnotacje",
"Note": "Notatka",
"Copied to clipboard": "Skopiowano do schowka",
"Export Annotations": "Eksportuj adnotacje",
"Auto Import on File Open": "Automatyczne importowanie przy otwieraniu pliku",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Zamień obszar kliknięcia na przewracanie",
"No chapters detected.": "Nie wykryto rozdziałów.",
"Failed to parse the EPUB file.": "Nie udało się przeanalizować pliku EPUB.",
"This book format is not supported.": "Ten format książki nie jest obsługiwany.",
"Unable to fetch the translation. Please log in first and try again.": "Nie można pobrać tłumaczenia. Proszę najpierw się zalogować i spróbować ponownie.",
"Group": "Grupa"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Hifenização",
"Identifier:": "Identificador:",
"Import Books": "Importar Livros",
"Invert Colors in Dark Mode": "Inverter Cores no Modo Escuro",
"Language:": "Idioma:",
"Layout": "Layout",
"Light Mode": "Modo Claro",
"Line Height": "Altura da Linha",
"Loading...": "Carregando...",
"Loc. {{currentPage}} / {{totalPage}}": "Loc. {{currentPage}} / {{totalPage}}",
"Logged in": "Conectado",
"Logged in as {{userDisplayName}}": "Conectado como {{userDisplayName}}",
"Match Case": "Diferenciar Maiúsculas e Minúsculas",
"Match Diacritics": "Corresponder Acentos",
"Match Whole Words": "Corresponder Palavras Inteiras",
"Maximum Block Size": "Tamanho Máximo do Bloco",
"Maximum Inline Size": "Tamanho Máximo em Linha",
"Maximum Number of Columns": "Número Máximo de Colunas",
"Minimum Font Size": "Tamanho Mínimo da Fonte",
"Misc": "Diversos",
@@ -76,7 +71,6 @@
"Notebook": "Caderno",
"Notes": "Notas",
"Open": "Abrir",
"Open Book": "Abrir Livro",
"Original Text": "Texto Original",
"Page": "Página",
"Paging Animation": "Animação de Página",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Livro excluído: {{title}}",
"Failed to delete book: {{title}}": "Falha ao excluir livro: {{title}}",
"Check Updates on Start": "Verificar Atualizações ao Iniciar",
"Insufficient storage quota": "Cota de armazenamento insuficiente"
"Insufficient storage quota": "Cota de armazenamento insuficiente",
"Font Weight": "Peso da Fonte",
"Line Spacing": "Espaçamento de Linha",
"Word Spacing": "Espaçamento de Palavra",
"Letter Spacing": "Espaçamento de Letra",
"Text Indent": "Recuo de Texto",
"Paragraph Margin": "Margem de Parágrafo",
"Override Book Layout": "Sobrescrever Layout do Livro",
"Untitled Group": "Grupo Sem Título",
"Group Books": "Agrupar Livros",
"Remove From Group": "Remover do Grupo",
"Create New Group": "Criar Novo Grupo",
"Deselect Book": "Desmarcar Livro",
"Download Book": "Baixar Livro",
"Deselect Group": "Desmarcar Grupo",
"Select Group": "Selecionar Grupo",
"Keep Screen Awake": "Manter a Tela Ativa",
"Email address": "Endereço de e-mail",
"Your Password": "Sua senha",
"Your email address": "Seu endereço de e-mail",
"Your password": "Sua senha",
"Sign in": "Entrar",
"Signing in...": "Entrando...",
"Sign in with {{provider}}": "Entrar com {{provider}}",
"Already have an account? Sign in": "Já tem uma conta? Entrar",
"Create a Password": "Criar uma senha",
"Sign up": "Cadastrar-se",
"Signing up...": "Cadastrando...",
"Dont have an account? Sign up": "Não tem uma conta? Cadastre-se",
"Check your email for the confirmation link": "Verifique seu e-mail para o link de confirmação",
"Signing in ...": "Entrando ...",
"Send a magic link email": "Enviar um link mágico por e-mail",
"Check your email for the magic link": "Verifique seu e-mail para o link mágico",
"Send reset password instructions": "Enviar instruções para redefinir a senha",
"Sending reset instructions ...": "Enviando instruções para redefinir a senha ...",
"Forgot your password?": "Esqueceu sua senha?",
"Check your email for the password reset link": "Verifique seu e-mail para o link de redefinição de senha",
"New Password": "Nova senha",
"Your new password": "Sua nova senha",
"Update password": "Atualizar senha",
"Updating password ...": "Atualizando senha ...",
"Your password has been updated": "Sua senha foi atualizada",
"Phone number": "Número de telefone",
"Your phone number": "Seu número de telefone",
"Token": "Token",
"Your OTP token": "Seu token OTP",
"Verify token": "Verificar token",
"Sign in with Google": "Entrar com o Google",
"Sign in with Apple": "Entrar com o Apple",
"Sign in with GitHub": "Entrar com o GitHub",
"Account": "Conta",
"Cloud Storage": "Armazenamento na nuvem",
"Failed to delete user. Please try again later.": "Falha ao excluir usuário. Por favor, tente novamente mais tarde.",
"Unlimited Offline/Online Reading": "Leitura offline/online ilimitada",
"Unlimited Cloud Sync Devices": "Sincronização ilimitada de dispositivos na nuvem",
"Essential Text-to-Speech Voices": "Vozes essenciais de texto para fala",
"DeepL Free Access": "Acesso gratuito ao DeepL",
"Community Support": "Suporte da comunidade",
"500 MB Cloud Sync Space": "500 MB de espaço de sincronização na nuvem",
"Includes All Free Tier Benefits": "Inclui todos os benefícios do plano gratuito",
"AI Summaries": "Resumos de IA",
"AI Translations": "Traduções de IA",
"Priority Support": "Suporte prioritário",
"DeepL Pro Access": "Acesso ao DeepL Pro",
"Expanded Text-to-Speech Voices": "Vozes ampliadas de texto para fala",
"2000 MB Cloud Sync Space": "2000 MB de espaço de sincronização na nuvem",
"Includes All Plus Tier Benefits": "Inclui todos os benefícios do plano Plus",
"Unlimited AI Summaries": "Resumos de IA ilimitados",
"Unlimited AI Translations": "Traduções de IA ilimitadas",
"Unlimited DeepL Pro Access": "Acesso ilimitado ao DeepL Pro",
"Advanced AI Tools": "Ferramentas avançadas de IA",
"Early Feature Access": "Acesso antecipado a recursos",
"10 GB Cloud Sync Space": "10 GB de espaço de sincronização na nuvem",
"Loading profile...": "Carregando perfil...",
"Features": "Recursos",
"Delete Account": "Excluir conta",
"Delete Your Account?": "Excluir sua conta?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Esta ação não pode ser desfeita. Todos os seus dados na nuvem serão excluídos permanentemente.",
"Delete Permanently": "Excluir permanentemente",
"Free Tier": "Plano gratuito",
"Plus Tier": "Plano Plus",
"Pro Tier": "Plano Pro",
"RTL Direction": "Direção RTL",
"Maximum Column Height": "Altura Máxima da Coluna",
"Maximum Column Width": "Largura Máxima da Coluna",
"Continuous Scroll": "Rolagem Contínua",
"Fullscreen": "Tela Cheia",
"No supported files found. Supported formats: {{formats}}": "Nenhum arquivo suportado encontrado. Formatos suportados: {{formats}}",
"Drop to Import Books": "Arraste para Importar Livros",
"Custom": "Personalizado",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Todo o mundo é um palco,\nE todos os homens e mulheres são meros atores;\nEles têm suas saídas e suas entradas,\nE um homem em seu tempo desempenha muitos papéis,\nSeus atos sendo sete idades.\n\n— William Shakespeare",
"Custom Theme": "Tema Personalizado",
"Theme Name": "Nome do Tema",
"Text Color": "Cor do Texto",
"Background Color": "Cor de Fundo",
"Preview": "Visualizar",
"Contrast": "Contraste",
"Sunset": "Pôr do Sol",
"Double Border": "Borda Dupla",
"Border Color": "Cor da Borda",
"Border Frame": "Moldura da Borda",
"Show Header": "Mostrar Cabeçalho",
"Show Footer": "Mostrar Rodapé",
"Small": "Pequeno",
"Large": "Grande",
"Auto": "Automático",
"Language": "Idioma",
"No annotations to export": "Nenhuma anotação para exportar",
"Author": "Autor",
"Exported from Readest": "Exportado do Readest",
"Highlights & Annotations": "Destaques e Anotações",
"Note": "Nota",
"Copied to clipboard": "Copiado para a área de transferência",
"Export Annotations": "Exportar Anotações",
"Auto Import on File Open": "Importação Automática ao Abrir Arquivo",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Trocar Área de Clique para Virar",
"No chapters detected.": "Nenhum capítulo detectado.",
"Failed to parse the EPUB file.": "Falha ao analisar o arquivo EPUB.",
"This book format is not supported.": "Este formato de livro não é suportado.",
"Unable to fetch the translation. Please log in first and try again.": "Não foi possível buscar a tradução. Faça login primeiro e tente novamente.",
"Group": "Grupo"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Перенос слов",
"Identifier:": "Идентификатор:",
"Import Books": "Импорт книг",
"Invert Colors in Dark Mode": "Инвертировать цвета в тёмной теме",
"Language:": "Язык:",
"Layout": "Макет",
"Light Mode": "Светлая тема",
"Line Height": "Межстрочный интервал",
"Loading...": "Загрузка...",
"Loc. {{currentPage}} / {{totalPage}}": "Поз. {{currentPage}} / {{totalPage}}",
"Logged in": "Выполнен вход",
"Logged in as {{userDisplayName}}": "Вход выполнен как {{userDisplayName}}",
"Match Case": "Учитывать регистр",
"Match Diacritics": "Учитывать диакритические знаки",
"Match Whole Words": "Только целые слова",
"Maximum Block Size": "Максимальный размер блока",
"Maximum Inline Size": "Максимальный размер строки",
"Maximum Number of Columns": "Максимальное количество колонок",
"Minimum Font Size": "Минимальный размер шрифта",
"Misc": "Разное",
@@ -76,7 +71,6 @@
"Notebook": "Блокнот",
"Notes": "Заметки",
"Open": "Открыть",
"Open Book": "Открыть книгу",
"Original Text": "Оригинальный текст",
"Page": "Страница",
"Paging Animation": "Анимация перелистывания",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Книга удалена: {{title}}",
"Failed to delete book: {{title}}": "Не удалось удалить книгу: {{title}}",
"Check Updates on Start": "Проверять обновления при запуске",
"Insufficient storage quota": "Недостаточно квоты хранилища"
"Insufficient storage quota": "Недостаточно квоты хранилища",
"Font Weight": "Насыщенность шрифта",
"Line Spacing": "Межстрочный интервал",
"Word Spacing": "Межсловный интервал",
"Letter Spacing": "Межбуквенный интервал",
"Text Indent": "Отступ текста",
"Paragraph Margin": "Отступ абзаца",
"Override Book Layout": "Переопределить макет книги",
"Untitled Group": "Группа без названия",
"Group Books": "Группировать книги",
"Remove From Group": "Удалить из группы",
"Create New Group": "Создать новую группу",
"Deselect Book": "Отменить выбор книги",
"Download Book": "Скачать книгу",
"Deselect Group": "Отменить выбор группы",
"Select Group": "Выбрать группу",
"Keep Screen Awake": "Не выключать экран",
"Email address": "Адрес электронной почты",
"Your Password": "Ваш пароль",
"Your email address": "Ваш адрес электронной почты",
"Your password": "Ваш пароль",
"Sign in": "Войти",
"Signing in...": "Вход...",
"Sign in with {{provider}}": "Войти с помощью {{provider}}",
"Already have an account? Sign in": "Уже есть аккаунт? Войдите",
"Create a Password": "Создать пароль",
"Sign up": "Зарегистрироваться",
"Signing up...": "Регистрация...",
"Dont have an account? Sign up": "Нет аккаунта? Зарегистрируйтесь",
"Check your email for the confirmation link": "Проверьте свою почту для подтверждающей ссылки",
"Signing in ...": "Вход ...",
"Send a magic link email": "Отправить магическую ссылку по электронной почте",
"Check your email for the magic link": "Проверьте свою почту для магической ссылки",
"Send reset password instructions": "Отправить инструкции по сбросу пароля",
"Sending reset instructions ...": "Отправка инструкций по сбросу пароля ...",
"Forgot your password?": "Забыли пароль?",
"Check your email for the password reset link": "Проверьте свою почту для ссылки для сброса пароля",
"New Password": "Новый пароль",
"Your new password": "Ваш новый пароль",
"Update password": "Обновить пароль",
"Updating password ...": "Обновление пароля ...",
"Your password has been updated": "Ваш пароль был обновлен",
"Phone number": "Номер телефона",
"Your phone number": "Ваш номер телефона",
"Token": "Токен",
"Your OTP token": "Ваш OTP токен",
"Verify token": "Проверить токен",
"Sign in with Google": "Войти через Google",
"Sign in with Apple": "Войти через Apple",
"Sign in with GitHub": "Войти через GitHub",
"Account": "Аккаунт",
"Cloud Storage": "Облачное хранилище",
"Failed to delete user. Please try again later.": "Не удалось удалить пользователя. Пожалуйста, повторите попытку позже.",
"Unlimited Offline/Online Reading": "Безлимитное чтение офлайн/онлайн",
"Unlimited Cloud Sync Devices": "Неограниченное количество устройств для облачной синхронизации",
"Essential Text-to-Speech Voices": "Основные голоса для преобразования текста в речь",
"DeepL Free Access": "Бесплатный доступ к DeepL",
"Community Support": "Поддержка сообщества",
"500 MB Cloud Sync Space": "500 МБ облачного пространства для синхронизации",
"Includes All Free Tier Benefits": "Включает все преимущества бесплатного тарифа",
"AI Summaries": "AI-резюме",
"AI Translations": "AI-переводы",
"Priority Support": "Приоритетная поддержка",
"DeepL Pro Access": "Доступ к DeepL Pro",
"Expanded Text-to-Speech Voices": "Расширенный набор голосов для преобразования текста в речь",
"2000 MB Cloud Sync Space": "2000 МБ облачного пространства для синхронизации",
"Includes All Plus Tier Benefits": "Включает все преимущества тарифа Plus",
"Unlimited AI Summaries": "Безлимитные AI-резюме",
"Unlimited AI Translations": "Безлимитные AI-переводы",
"Unlimited DeepL Pro Access": "Неограниченный доступ к DeepL Pro",
"Advanced AI Tools": "Продвинутые AI-инструменты",
"Early Feature Access": "Ранний доступ к новым функциям",
"10 GB Cloud Sync Space": "10 ГБ облачного пространства для синхронизации",
"Loading profile...": "Загрузка профиля...",
"Features": "Функции",
"Delete Account": "Удалить аккаунт",
"Delete Your Account?": "Удалить ваш аккаунт?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Это действие нельзя отменить. Все ваши данные в облаке будут удалены безвозвратно.",
"Delete Permanently": "Удалить навсегда",
"Free Tier": "Бесплатный тариф",
"Plus Tier": "Тариф Plus",
"Pro Tier": "Тариф Pro",
"RTL Direction": "Направление RTL",
"Maximum Column Height": "Максимальная высота колонки",
"Maximum Column Width": "Максимальная ширина колонки",
"Continuous Scroll": "Непрерывная прокрутка",
"Fullscreen": "Полноэкранный режим",
"No supported files found. Supported formats: {{formats}}": "Поддерживаемые файлы не найдены. Поддерживаемые форматы: {{formats}}",
"Drop to Import Books": "Перетащите сюда книги для импорта",
"Custom": "Пользовательский",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Весь мир — театр,\nИ все мужчины и женщины — просто актёры;\nУ них есть свои выходы и входы,\nИ один человек в своё время играет много ролей,\nЕго поступки — это семь веков.\n\n— Уильям Шекспир",
"Custom Theme": "Пользовательская тема",
"Theme Name": "Название темы",
"Text Color": "Цвет текста",
"Background Color": "Цвет фона",
"Preview": "Предпросмотр",
"Contrast": "Контраст",
"Sunset": "Закат",
"Double Border": "Двойная граница",
"Border Color": "Цвет границы",
"Border Frame": "Граница рамки",
"Show Header": "Показать заголовок",
"Show Footer": "Показать нижний колонтитул",
"Small": "Маленький",
"Large": "Большой",
"Auto": "Авто",
"Language": "Язык",
"No annotations to export": "Нет аннотаций для экспорта",
"Author": "Автор",
"Exported from Readest": "Экспортировано из Readest",
"Highlights & Annotations": "Выделения и аннотации",
"Note": "Заметка",
"Copied to clipboard": "Скопировано в буфер обмена",
"Export Annotations": "Экспортировать аннотации",
"Auto Import on File Open": "Автоматический импорт при открытии файла",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Переключить область клика для переворота",
"No chapters detected.": "Не обнаружено глав.",
"Failed to parse the EPUB file.": "Не удалось разобрать файл EPUB.",
"This book format is not supported.": "Этот формат книги не поддерживается.",
"Unable to fetch the translation. Please log in first and try again.": "Не удалось получить перевод. Пожалуйста, войдите в систему и попробуйте снова.",
"Group": "Группа"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Heceleme",
"Identifier:": "Tanımlayıcı:",
"Import Books": "Kitapları İçe Aktar",
"Invert Colors in Dark Mode": "Karanlık Modda Renkleri Ters Çevir",
"Language:": "Dil:",
"Layout": "Düzen",
"Light Mode": "Aydınlık Mod",
"Line Height": "Satır Yüksekliği",
"Loading...": "Yükleniyor...",
"Loc. {{currentPage}} / {{totalPage}}": "Konum {{currentPage}} / {{totalPage}}",
"Logged in": "Giriş Yapıldı",
"Logged in as {{userDisplayName}}": "{{userDisplayName}} olarak giriş yapıldı",
"Match Case": "Büyük/Küçük Harf Eşleştir",
"Match Diacritics": "Aksan İşaretlerini Eşleştir",
"Match Whole Words": "Tam Kelimeleri Eşleştir",
"Maximum Block Size": "Maksimum Blok Boyutu",
"Maximum Inline Size": "Maksimum Satır İçi Boyut",
"Maximum Number of Columns": "Maksimum Sütun Sayısı",
"Minimum Font Size": "Minimum Yazı Boyutu",
"Misc": "Diğer",
@@ -76,7 +71,6 @@
"Notebook": "Not Defteri",
"Notes": "Notlar",
"Open": "Aç",
"Open Book": "Kitabı Aç",
"Original Text": "Orijinal Metin",
"Page": "Sayfa",
"Paging Animation": "Sayfa Çevirme Animasyonu",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Kitap silindi: {{title}}",
"Failed to delete book: {{title}}": "Kitap silinemedi: {{title}}",
"Check Updates on Start": "Başlangıçta Güncellemeleri Kontrol Et",
"Insufficient storage quota": "Yetersiz depolama kotası"
"Insufficient storage quota": "Yetersiz depolama kotası",
"Font Weight": "Yazı Tipi Ağırlığı",
"Line Spacing": "Satır Aralığı",
"Word Spacing": "Kelime Aralığı",
"Letter Spacing": "Harf Aralığı",
"Text Indent": "Metin Girintisi",
"Paragraph Margin": "Paragraf Kenarı",
"Override Book Layout": "Kitap Düzenini Geçersiz Kıl",
"Untitled Group": "Başlıksız Grup",
"Group Books": "Kitapları Grupla",
"Remove From Group": "Grubu Kaldır",
"Create New Group": "Yeni Grup Oluştur",
"Deselect Book": "Kitabı Seçme",
"Download Book": "Kitabı İndir",
"Deselect Group": "Grubu Seçme",
"Select Group": "Grup Seç",
"Keep Screen Awake": "Ekranı Açık Tut",
"Email address": "E-posta adresi",
"Your Password": "Şifreniz",
"Your email address": "E-posta adresiniz",
"Your password": "Şifreniz",
"Sign in": "Giriş yap",
"Signing in...": "Giriş yapılıyor...",
"Sign in with {{provider}}": "{{provider}} ile giriş yap",
"Already have an account? Sign in": "Hesabınız var mı? Giriş yapın",
"Create a Password": "Şifre oluştur",
"Sign up": "Kaydol",
"Signing up...": "Kaydolunuyor...",
"Dont have an account? Sign up": "Hesabınız yok mu? Kaydolun",
"Check your email for the confirmation link": "Onay bağlantısı için e-posta adresinizi kontrol edin",
"Signing in ...": "Giriş yapılıyor...",
"Send a magic link email": "Sihirli bağlantı e-postası gönder",
"Check your email for the magic link": "Sihirli bağlantı için e-posta adresinizi kontrol edin",
"Send reset password instructions": "Şifre sıfırlama talimatları gönder",
"Sending reset instructions ...": "Şifre sıfırlama talimatları gönderiliyor...",
"Forgot your password?": "Şifrenizi mi unuttunuz?",
"Check your email for the password reset link": "Şifre sıfırlama bağlantısı için e-posta adresinizi kontrol edin",
"New Password": "Yeni şifre",
"Your new password": "Yeni şifreniz",
"Update password": "Şifreyi güncelle",
"Updating password ...": "Şifre güncelleniyor...",
"Your password has been updated": "Şifreniz güncellendi",
"Phone number": "Telefon numarası",
"Your phone number": "Telefon numaranız",
"Token": "Token",
"Your OTP token": "OTP token'ınız",
"Verify token": "Token'ı doğrula",
"Sign in with Google": "Google ile giriş yap",
"Sign in with Apple": "Apple ile giriş yap",
"Sign in with GitHub": "GitHub ile giriş yap",
"Account": "Hesap",
"Cloud Storage": "Bulut Depolama",
"Failed to delete user. Please try again later.": "Kullanıcı silinemedi. Lütfen daha sonra tekrar deneyin.",
"Unlimited Offline/Online Reading": "Sınırsız Çevrimdışı/Çevrimiçi Okuma",
"Unlimited Cloud Sync Devices": "Sınırsız Bulut Senkronizasyon Cihazları",
"Essential Text-to-Speech Voices": "Temel Metinden Sese Dönüştürme Sesleri",
"DeepL Free Access": "DeepL Ücretsiz Erişim",
"Community Support": "Topluluk Desteği",
"500 MB Cloud Sync Space": "500 MB Bulut Senkronizasyon Alanı",
"Includes All Free Tier Benefits": "Tüm Ücretsiz Paket Avantajlarını İçerir",
"AI Summaries": "Yapay Zeka Özetleri",
"AI Translations": "Yapay Zeka Çevirileri",
"Priority Support": "Öncelikli Destek",
"DeepL Pro Access": "DeepL Pro Erişimi",
"Expanded Text-to-Speech Voices": "Genişletilmiş Metinden Sese Dönüştürme Sesleri",
"2000 MB Cloud Sync Space": "2000 MB Bulut Senkronizasyon Alanı",
"Includes All Plus Tier Benefits": "Tüm Plus Paket Avantajlarını İçerir",
"Unlimited AI Summaries": "Sınırsız Yapay Zeka Özetleri",
"Unlimited AI Translations": "Sınırsız Yapay Zeka Çevirileri",
"Unlimited DeepL Pro Access": "Sınırsız DeepL Pro Erişimi",
"Advanced AI Tools": "Gelişmiş Yapay Zeka Araçları",
"Early Feature Access": "Erken Özellik Erişimi",
"10 GB Cloud Sync Space": "10 GB Bulut Senkronizasyon Alanı",
"Loading profile...": "Profil yükleniyor...",
"Features": "Özellikler",
"Delete Account": "Hesabı Sil",
"Delete Your Account?": "Hesabınızı Silmek İstiyor musunuz?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Bu işlem geri alınamaz. Buluttaki tüm verileriniz kalıcı olarak silinecektir.",
"Delete Permanently": "Kalıcı Olarak Sil",
"Free Tier": "Ücretsiz Paket",
"Plus Tier": "Plus Paket",
"Pro Tier": "Pro Paket",
"RTL Direction": "RTL Yönü",
"Maximum Column Height": "Maksimum Sütun Yüksekliği",
"Maximum Column Width": "Maksimum Sütun Genişliği",
"Continuous Scroll": "Sürekli Kaydırma",
"Fullscreen": "Tam Ekran",
"No supported files found. Supported formats: {{formats}}": "Desteklenen dosya bulunamadı. Desteklenen formatlar: {{formats}}",
"Drop to Import Books": "Kitapları İçe Aktarmak İçin Bırak",
"Custom": "Özel",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Tüm dünya bir sahnedir,\nVe tüm erkekler ve kadınlar sadece oyunculardır;\nOnların çıkışları ve girişleri vardır,\nVe bir adam zamanında birçok rol oynar,\nOnun eylemleri yedi yaşındadır.\n\n— William Shakespeare",
"Custom Theme": "Özel Tema",
"Theme Name": "Tema Adı",
"Text Color": "Metin Rengi",
"Background Color": "Arka Plan Rengi",
"Preview": "Önizleme",
"Contrast": "Kontrast",
"Sunset": "Gün Batımı",
"Double Border": "Çift Sınır",
"Border Color": "Sınır Rengi",
"Border Frame": "Sınır Çerçevesi",
"Show Header": "Başlık Göster",
"Show Footer": "Altbilgi Göster",
"Small": "Küçük",
"Large": "Büyük",
"Auto": "Otomatik",
"Language": "Dil",
"No annotations to export": "Dışa aktarılacak not yok",
"Author": "Yazar",
"Exported from Readest": "Readest'ten dışa aktarıldı",
"Highlights & Annotations": "Vurgular ve Notlar",
"Note": "Not",
"Copied to clipboard": "Panoya kopyalandı",
"Export Annotations": "Notları Dışa Aktar",
"Auto Import on File Open": "Dosya Açıldığında Otomatik İçe Aktar",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Tıkla-Çevir Alanını Değiştir",
"No chapters detected.": "Bölüm bulunamadı.",
"Failed to parse the EPUB file.": "EPUB dosyası ayrıştırılamadı.",
"This book format is not supported.": "Bu kitap formatı desteklenmiyor.",
"Unable to fetch the translation. Please log in first and try again.": "Çeviri alınamıyor. Lütfen önce giriş yapın ve tekrar deneyin.",
"Group": "Grup"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Перенесення слів",
"Identifier:": "Ідентифікатор:",
"Import Books": "Імпортувати книги",
"Invert Colors in Dark Mode": "Інвертувати кольори в темному режимі",
"Language:": "Мова:",
"Layout": "Макет",
"Light Mode": "Світлий режим",
"Line Height": "Висота рядка",
"Loading...": "Завантаження...",
"Loc. {{currentPage}} / {{totalPage}}": "Поз. {{currentPage}} / {{totalPage}}",
"Logged in": "Увійшли",
"Logged in as {{userDisplayName}}": "Увійшли як {{userDisplayName}}",
"Match Case": "Враховувати регістр",
"Match Diacritics": "Враховувати діакритичні знаки",
"Match Whole Words": "Шукати цілі слова",
"Maximum Block Size": "Максимальний розмір блоку",
"Maximum Inline Size": "Максимальний розмір рядка",
"Maximum Number of Columns": "Максимальна кількість колонок",
"Minimum Font Size": "Мінімальний розмір шрифту",
"Misc": "Різне",
@@ -76,7 +71,6 @@
"Notebook": "Нотатник",
"Notes": "Нотатки",
"Open": "Відкрити",
"Open Book": "Відкрити книгу",
"Original Text": "Оригінальний текст",
"Page": "Сторінка",
"Paging Animation": "Анімація гортання",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Книгу видалено: {{title}}",
"Failed to delete book: {{title}}": "Не вдалося видалити книгу: {{title}}",
"Check Updates on Start": "Перевіряти оновлення при запуску",
"Insufficient storage quota": "Недостатньо квоти сховища"
"Insufficient storage quota": "Недостатньо квоти сховища",
"Font Weight": "Насиченість шрифту",
"Line Spacing": "Міжрядковий інтервал",
"Word Spacing": "Міжслівний інтервал",
"Letter Spacing": "Міжбуквений інтервал",
"Text Indent": "Відступ тексту",
"Paragraph Margin": "Відступ абзацу",
"Override Book Layout": "Перевизначити макет книги",
"Untitled Group": "Група без назви",
"Group Books": "Групувати книги",
"Remove From Group": "Видалити з групи",
"Create New Group": "Створити нову групу",
"Deselect Book": "Скасувати вибір книги",
"Download Book": "Завантажити книгу",
"Deselect Group": "Скасувати вибір групи",
"Select Group": "Вибрати групу",
"Keep Screen Awake": "Не вимикати екран",
"Email address": "Адреса електронної пошти",
"Your Password": "Ваш пароль",
"Your email address": "Ваша електронна адреса",
"Your password": "Ваш пароль",
"Sign in": "Увійти",
"Signing in...": "Вхід...",
"Sign in with {{provider}}": "Увійти через {{provider}}",
"Already have an account? Sign in": "Уже є акаунт? Увійти",
"Create a Password": "Створити пароль",
"Sign up": "Зареєструватися",
"Signing up...": "Реєстрація...",
"Dont have an account? Sign up": "Немає акаунту? Зареєструйтеся",
"Check your email for the confirmation link": "Перевірте свою електронну пошту для підтвердження посилання",
"Signing in ...": "Увійти...",
"Send a magic link email": "Відправити магічне посилання на електронну пошту",
"Check your email for the magic link": "Перевірте свою електронну пошту для магічного посилання",
"Send reset password instructions": "Надіслати інструкції для скидання пароля",
"Sending reset instructions ...": "Надсилаються інструкції для скидання пароля...",
"Forgot your password?": "Забули пароль?",
"Check your email for the password reset link": "Перевірте свою електронну пошту для посилання на скидання пароля",
"New Password": "Новий пароль",
"Your new password": "Ваш новий пароль",
"Update password": "Оновити пароль",
"Updating password ...": "Оновлення пароля...",
"Your password has been updated": "Ваш пароль оновлено",
"Phone number": "Номер телефону",
"Your phone number": "Ваш номер телефону",
"Token": "Токен",
"Your OTP token": "Ваш OTP токен",
"Verify token": "Перевірити токен",
"Sign in with Google": "Увійти через Google",
"Sign in with Apple": "Увійти через Apple",
"Sign in with GitHub": "Увійти через GitHub",
"Account": "Обліковий запис",
"Cloud Storage": "Хмарне сховище",
"Failed to delete user. Please try again later.": "Не вдалося видалити користувача. Будь ласка, спробуйте пізніше.",
"Unlimited Offline/Online Reading": "Необмежене читання офлайн/онлайн",
"Unlimited Cloud Sync Devices": "Необмежена кількість пристроїв для хмарної синхронізації",
"Essential Text-to-Speech Voices": "Основні голоси для перетворення тексту в мовлення",
"DeepL Free Access": "Безкоштовний доступ до DeepL",
"Community Support": "Підтримка спільноти",
"500 MB Cloud Sync Space": "500 МБ простору для хмарної синхронізації",
"Includes All Free Tier Benefits": "Включає всі переваги безкоштовного тарифу",
"AI Summaries": "AI-резюме",
"AI Translations": "AI-переклади",
"Priority Support": "Пріоритетна підтримка",
"DeepL Pro Access": "Доступ до DeepL Pro",
"Expanded Text-to-Speech Voices": "Розширений набір голосів для перетворення тексту в мовлення",
"2000 MB Cloud Sync Space": "2000 МБ простору для хмарної синхронізації",
"Includes All Plus Tier Benefits": "Включає всі переваги тарифу Plus",
"Unlimited AI Summaries": "Необмежені AI-резюме",
"Unlimited AI Translations": "Необмежені AI-переклади",
"Unlimited DeepL Pro Access": "Необмежений доступ до DeepL Pro",
"Advanced AI Tools": "Розширені AI-інструменти",
"Early Feature Access": "Ранній доступ до нових функцій",
"10 GB Cloud Sync Space": "10 ГБ простору для хмарної синхронізації",
"Loading profile...": "Завантаження профілю...",
"Features": "Функції",
"Delete Account": "Видалити обліковий запис",
"Delete Your Account?": "Видалити ваш обліковий запис?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Цю дію неможливо скасувати. Всі ваші дані в хмарі будуть повністю видалені.",
"Delete Permanently": "Видалити назавжди",
"Free Tier": "Безкоштовний тариф",
"Plus Tier": "Тариф Plus",
"Pro Tier": "Тариф Pro",
"RTL Direction": "Напрямок RTL",
"Maximum Column Height": "Максимальна висота колонки",
"Maximum Column Width": "Максимальна ширина колонки",
"Continuous Scroll": "Постійна прокрутка",
"Fullscreen": "Повноекранний",
"No supported files found. Supported formats: {{formats}}": "Не знайдено підтримуваних файлів. Підтримувані формати: {{formats}}",
"Drop to Import Books": "Перетягніть для імпорту книг",
"Custom": "Користувацький",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Весь світ — театр,\nІ всі чоловіки та жінки — просто актори;\nУ них є свої виходи та входи,\nІ один чоловік у свій час грає багато ролей,\nЙого вчинки — це сім віков.\n\n— Вільям Шекспір",
"Custom Theme": "Користувацька тема",
"Theme Name": "Назва теми",
"Text Color": "Колір тексту",
"Background Color": "Колір фону",
"Preview": "Попередній перегляд",
"Contrast": "Контраст",
"Sunset": "Захід сонця",
"Double Border": "Подвійна рамка",
"Border Color": "Колір рамки",
"Border Frame": "Рамка рамки",
"Show Header": "Показати заголовок",
"Show Footer": "Показати нижню частину",
"Small": "Малий",
"Large": "Великий",
"Auto": "Автоматичний",
"Language": "Мова",
"No annotations to export": "Немає анотацій для експорту",
"Author": "Автор",
"Exported from Readest": "Експортовано з Readest",
"Highlights & Annotations": "Виділення та анотації",
"Note": "Примітка",
"Copied to clipboard": "Скопійовано в буфер обміну",
"Export Annotations": "Експортувати анотації",
"Auto Import on File Open": "Автоматичний імпорт при відкритті файлу",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Поміняти місцями область кліку для перевороту",
"No chapters detected.": "Не виявлено жодного розділу.",
"Failed to parse the EPUB file.": "Не вдалося розібрати файл EPUB.",
"This book format is not supported.": "Цей формат книги не підтримується.",
"Unable to fetch the translation. Please log in first and try again.": "Не вдалося отримати переклад. Будь ласка, спочатку увійдіть у систему та спробуйте ще раз.",
"Group": "Група"
}
@@ -53,20 +53,15 @@
"Hyphenation": "Gạch nối từ",
"Identifier:": "Định danh:",
"Import Books": "Nhập sách",
"Invert Colors in Dark Mode": "Đảo màu trong chế độ tối",
"Language:": "Ngôn ngữ:",
"Layout": "Bố cục",
"Light Mode": "Chế độ sáng",
"Line Height": "Độ cao dòng",
"Loading...": "Đang tải...",
"Loc. {{currentPage}} / {{totalPage}}": "Vị trí {{currentPage}} / {{totalPage}}",
"Logged in": "Đã đăng nhập",
"Logged in as {{userDisplayName}}": "Đăng nhập với tên {{userDisplayName}}",
"Match Case": "Phân biệt chữ hoa/thường",
"Match Diacritics": "Phân biệt dấu",
"Match Whole Words": "Khớp toàn bộ từ",
"Maximum Block Size": "Kích thước khối tối đa",
"Maximum Inline Size": "Kích thước nội tuyến tối đa",
"Maximum Number of Columns": "Số cột tối đa",
"Minimum Font Size": "Cỡ chữ tối thiểu",
"Misc": "Khác",
@@ -76,7 +71,6 @@
"Notebook": "Sổ ghi chép",
"Notes": "Ghi chú",
"Open": "Mở",
"Open Book": "Mở sách",
"Original Text": "Văn bản gốc",
"Page": "Trang",
"Paging Animation": "Hiệu ứng lật trang",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "Sách đã xóa: {{title}}",
"Failed to delete book: {{title}}": "Không thể xóa sách: {{title}}",
"Check Updates on Start": "Kiểm tra cập nhật khi khởi động",
"Insufficient storage quota": "Không đủ lượng lưu trữ"
"Insufficient storage quota": "Không đủ lượng lưu trữ",
"Font Weight": "Độ đậm của phông chữ",
"Line Spacing": "Khoảng cách dòng",
"Word Spacing": "Khoảng cách từ",
"Letter Spacing": "Khoảng cách chữ",
"Text Indent": "Thụt lề",
"Paragraph Margin": "Lề đoạn",
"Override Book Layout": "Ghi đè bố cục sách",
"Untitled Group": "Nhóm không có tiêu đề",
"Group Books": "Nhóm sách",
"Remove From Group": "Xóa khỏi nhóm",
"Create New Group": "Tạo nhóm mới",
"Deselect Book": "Bỏ chọn sách",
"Download Book": "Tải sách",
"Deselect Group": "Bỏ chọn nhóm",
"Select Group": "Chọn nhóm",
"Keep Screen Awake": "Giữ màn hình luôn bật",
"Email address": "Địa chỉ email",
"Your Password": "Mật khẩu của bạn",
"Your email address": "Địa chỉ email của bạn",
"Your password": "Mật khẩu của bạn",
"Sign in": "Đăng nhập",
"Signing in...": "Đang đăng nhập...",
"Sign in with {{provider}}": "Đăng nhập với {{provider}}",
"Already have an account? Sign in": "Đã có tài khoản? Đăng nhập",
"Create a Password": "Tạo mật khẩu",
"Sign up": "Đăng ký",
"Signing up...": "Đang đăng ký...",
"Dont have an account? Sign up": "Chưa có tài khoản? Đăng ký",
"Check your email for the confirmation link": "Kiểm tra email của bạn để nhận liên kết xác nhận",
"Signing in ...": "Đang đăng nhập ...",
"Send a magic link email": "Gửi email liên kết ma thuật",
"Check your email for the magic link": "Kiểm tra email của bạn để nhận liên kết ma thuật",
"Send reset password instructions": "Gửi hướng dẫn đặt lại mật khẩu",
"Sending reset instructions ...": "Đang gửi hướng dẫn đặt lại mật khẩu ...",
"Forgot your password?": "Quên mật khẩu?",
"Check your email for the password reset link": "Kiểm tra email của bạn để nhận liên kết đặt lại mật khẩu",
"New Password": "Mật khẩu mới",
"Your new password": "Mật khẩu mới của bạn",
"Update password": "Cập nhật mật khẩu",
"Updating password ...": "Đang cập nhật mật khẩu ...",
"Your password has been updated": "Mật khẩu của bạn đã được cập nhật",
"Phone number": "Số điện thoại",
"Your phone number": "Số điện thoại của bạn",
"Token": "Mã token",
"Your OTP token": "Mã OTP của bạn",
"Verify token": "Xác minh mã token",
"Sign in with Google": "Đăng nhập với Google",
"Sign in with Apple": "Đăng nhập với Apple",
"Sign in with GitHub": "Đăng nhập với GitHub",
"Account": "Tài khoản",
"Cloud Storage": "Lưu trữ đám mây",
"Failed to delete user. Please try again later.": "Không thể xóa người dùng. Vui lòng thử lại sau.",
"Unlimited Offline/Online Reading": "Đọc ngoại tuyến/trực tuyến không giới hạn",
"Unlimited Cloud Sync Devices": "Đồng bộ hóa thiết bị đám mây không giới hạn",
"Essential Text-to-Speech Voices": "Giọng nói chuyển văn bản thành giọng nói cơ bản",
"DeepL Free Access": "Truy cập DeepL miễn phí",
"Community Support": "Hỗ trợ cộng đồng",
"500 MB Cloud Sync Space": "500 MB không gian đồng bộ hóa đám mây",
"Includes All Free Tier Benefits": "Bao gồm tất cả lợi ích của gói miễn phí",
"AI Summaries": "Tóm tắt AI",
"AI Translations": "Dịch thuật AI",
"Priority Support": "Hỗ trợ ưu tiên",
"DeepL Pro Access": "Truy cập DeepL Pro",
"Expanded Text-to-Speech Voices": "Giọng nói chuyển văn bản thành giọng nói mở rộng",
"2000 MB Cloud Sync Space": "2000 MB không gian đồng bộ hóa đám mây",
"Includes All Plus Tier Benefits": "Bao gồm tất cả lợi ích của gói Plus",
"Unlimited AI Summaries": "Tóm tắt AI không giới hạn",
"Unlimited AI Translations": "Dịch thuật AI không giới hạn",
"Unlimited DeepL Pro Access": "Truy cập DeepL Pro không giới hạn",
"Advanced AI Tools": "Công cụ AI nâng cao",
"Early Feature Access": "Truy cập tính năng sớm",
"10 GB Cloud Sync Space": "10 GB không gian đồng bộ hóa đám mây",
"Loading profile...": "Đang tải hồ sơ...",
"Features": "Tính năng",
"Delete Account": "Xóa tài khoản",
"Delete Your Account?": "Xóa tài khoản của bạn?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "Hành động này không thể hoàn tác. Tất cả dữ liệu của bạn trên đám mây sẽ bị xóa vĩnh viễn.",
"Delete Permanently": "Xóa vĩnh viễn",
"Free Tier": "Gói miễn phí",
"Plus Tier": "Gói Plus",
"Pro Tier": "Gói Pro",
"RTL Direction": "Hướng RTL",
"Maximum Column Height": "Chiều cao cột tối đa",
"Maximum Column Width": "Chiều rộng cột tối đa",
"Continuous Scroll": "Cuộn liên tục",
"Fullscreen": "Toàn màn hình",
"No supported files found. Supported formats: {{formats}}": "Không tìm thấy tệp được hỗ trợ. Định dạng được hỗ trợ: {{formats}}",
"Drop to Import Books": "Kéo và thả để nhập sách",
"Custom": "Tùy chỉnh",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "Cả thế giới này là một sân khấu,\nVà tất cả đàn ông và phụ nữ chỉ là những diễn viên;\nHọ có cửa ra và cửa vào của mình,\nVà một người trong cuộc đời mình đóng nhiều vai,\nHành động của mình là bảy tuổi.\n\n— William Shakespeare",
"Custom Theme": "Chủ đề tùy chỉnh",
"Theme Name": "Tên chủ đề",
"Text Color": "Màu văn bản",
"Background Color": "Màu nền",
"Preview": "Xem trước",
"Contrast": "Tương phản",
"Sunset": "Hoàng hôn",
"Double Border": "Đôi viền",
"Border Color": "Màu viền",
"Border Frame": "Khung viền",
"Show Header": "Hiển thị tiêu đề",
"Show Footer": "Hiển thị chân trang",
"Small": "Nhỏ",
"Large": "Lớn",
"Auto": "Tự động",
"Language": "Ngôn ngữ",
"No annotations to export": "Không có chú thích để xuất",
"Author": "Tác giả",
"Exported from Readest": "Đã xuất từ Readest",
"Highlights & Annotations": "Điểm nổi bật & Chú thích",
"Note": "Ghi chú",
"Copied to clipboard": "Đã sao chép vào bảng ghi",
"Export Annotations": "Xuất chú thích",
"Auto Import on File Open": "Tự động nhập khi mở tệp",
"LXGW WenKai GB Screen": "LXGW WenKai",
"Swap Click-to-Flip Area": "Hoán đổi khu vực nhấp để lật trang",
"No chapters detected.": "Không phát hiện thấy chương nào.",
"Failed to parse the EPUB file.": "Không thể phân tích tệp EPUB.",
"This book format is not supported.": "Định dạng sách này không được hỗ trợ.",
"Unable to fetch the translation. Please log in first and try again.": "Không thể tải dịch vụ. Vui lòng đăng nhập trước và thử lại.",
"Group": "Nhóm"
}
@@ -53,20 +53,15 @@
"Hyphenation": "断字",
"Identifier:": "识别码",
"Import Books": "导入书籍",
"Invert Colors in Dark Mode": "深色主题下反色",
"Language:": "语言",
"Layout": "布局",
"Light Mode": "浅色主题",
"Line Height": "行高",
"Loading...": "加载中...",
"Loc. {{currentPage}} / {{totalPage}}": "位置 {{currentPage}} / {{totalPage}}",
"Logged in": "已登录",
"Logged in as {{userDisplayName}}": "{{userDisplayName}} 已登录",
"Match Case": "匹配大小写",
"Match Diacritics": "匹配重音符号",
"Match Whole Words": "匹配整个单词",
"Maximum Block Size": "内容最大宽度",
"Maximum Inline Size": "每栏最大宽度",
"Maximum Number of Columns": "分栏数",
"Minimum Font Size": "最小字号",
"Misc": "杂项",
@@ -76,7 +71,6 @@
"Notebook": "笔记本",
"Notes": "笔记",
"Open": "打开",
"Open Book": "打开书籍",
"Original Text": "原文",
"Page": "页面",
"Paging Animation": "翻页动画",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "书籍已删除:{{title}}",
"Failed to delete book: {{title}}": "删除书籍失败:{{title}}",
"Check Updates on Start": "启动时检查更新",
"Insufficient storage quota": "云存储空间不足"
"Insufficient storage quota": "云存储空间不足",
"Font Weight": "字重",
"Line Spacing": "行间距",
"Word Spacing": "词间距",
"Letter Spacing": "字间距",
"Text Indent": "首行缩进",
"Paragraph Margin": "段间距",
"Override Book Layout": "覆盖版面布局",
"Untitled Group": "无标题分组",
"Group Books": "分组书籍",
"Remove From Group": "从分组中移除",
"Create New Group": "创建新分组",
"Deselect Book": "取消选择书籍",
"Download Book": "下载书籍",
"Deselect Group": "取消选择分组",
"Select Group": "选择分组",
"Keep Screen Awake": "保持屏幕常亮",
"Email address": "电子邮件地址",
"Your Password": "您的密码",
"Your email address": "您的电子邮件地址",
"Your password": "您的密码",
"Sign in": "登录",
"Signing in...": "正在登录...",
"Sign in with {{provider}}": "使用 {{provider}} 登录",
"Already have an account? Sign in": "已经有账号?登录",
"Create a Password": "创建密码",
"Sign up": "注册",
"Signing up...": "正在注册...",
"Dont have an account? Sign up": "没有账号?注册",
"Check your email for the confirmation link": "检查您的电子邮件以获取确认链接",
"Signing in ...": "正在登录...",
"Send a magic link email": "发送魔法链接邮件",
"Check your email for the magic link": "检查您的电子邮件以获取魔法链接",
"Send reset password instructions": "发送重置密码说明",
"Sending reset instructions ...": "正在发送重置密码说明...",
"Forgot your password?": "忘记密码?",
"Check your email for the password reset link": "检查您的电子邮件以获取密码重置链接",
"New Password": "新密码",
"Your new password": "您的新密码",
"Update password": "更新密码",
"Updating password ...": "正在更新密码...",
"Your password has been updated": "您的密码已更新",
"Phone number": "电话号码",
"Your phone number": "您的电话号码",
"Token": "令牌",
"Your OTP token": "您的 OTP 令牌",
"Verify token": "验证令牌",
"Sign in with Google": "使用 Google 登录",
"Sign in with Apple": "使用 Apple 登录",
"Sign in with GitHub": "使用 GitHub 登录",
"Account": "账户",
"Cloud Storage": "云存储",
"Failed to delete user. Please try again later.": "删除用户失败。请稍后重试。",
"Unlimited Offline/Online Reading": "无限离线和在线阅读",
"Unlimited Cloud Sync Devices": "无限云同步设备个数",
"Essential Text-to-Speech Voices": "基础 TTS 语音包",
"DeepL Free Access": "免费版 DeepL 翻译",
"Community Support": "社区支持",
"500 MB Cloud Sync Space": "500 MB 云同步空间",
"Includes All Free Tier Benefits": "包含所有免费版权益",
"AI Summaries": "AI 摘要",
"AI Translations": "AI 翻译",
"Priority Support": "优先支持",
"DeepL Pro Access": "专业版 DeepL 翻译",
"Expanded Text-to-Speech Voices": "更多文本转语音声音",
"2000 MB Cloud Sync Space": "2000 MB 云同步空间",
"Includes All Plus Tier Benefits": "包含所有增强版权益",
"Unlimited AI Summaries": "无限使用 AI 摘要",
"Unlimited AI Translations": "无限使用 AI 翻译",
"Unlimited DeepL Pro Access": "无限使用专业版 DeepL 翻译",
"Advanced AI Tools": "高级 AI 工具",
"Early Feature Access": "抢先体验新功能",
"10 GB Cloud Sync Space": "10 GB 云同步空间",
"Loading profile...": "加载个人资料中...",
"Features": "功能特性",
"Delete Account": "删除账户",
"Delete Your Account?": "删除您的账户?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "此操作无法撤销。您在云端的所有数据将被永久删除。",
"Delete Permanently": "永久删除",
"Free Tier": "免费版",
"Plus Tier": "增强版",
"Pro Tier": "专业版",
"RTL Direction": "从右向左",
"Maximum Column Height": "最大列高",
"Maximum Column Width": "最大列宽",
"Continuous Scroll": "连续滚动",
"Fullscreen": "全屏",
"No supported files found. Supported formats: {{formats}}": "未找到支持的文件。支持的格式:{{formats}}",
"Drop to Import Books": "拖放导入书籍",
"Custom": "自定义",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "世界是座舞台, \n所有男女都只是演员; \n各有其出场和入场; \n每个人皆扮演许多角色, \n而演出共分为七个阶段。\n\n——威廉·莎士比亚",
"Custom Theme": "自定义主题",
"Theme Name": "主题名称",
"Text Color": "文本颜色",
"Background Color": "背景颜色",
"Preview": "预览",
"Contrast": "对比",
"Sunset": "日落",
"Double Border": "显示版框",
"Border Color": "版框颜色",
"Border Frame": "页面版框",
"Show Header": "显示页眉",
"Show Footer": "显示页脚",
"Small": "小",
"Large": "大",
"Auto": "自动",
"Language": "语言",
"No annotations to export": "没有要导出的笔记",
"Author": "作者",
"Exported from Readest": "从 Readest 导出",
"Highlights & Annotations": "划线和笔记",
"Note": "笔记",
"Copied to clipboard": "已复制到剪贴板",
"Export Annotations": "导出笔记",
"Auto Import on File Open": "打开文件时自动导入",
"LXGW WenKai GB Screen": "霞鹜文楷",
"Swap Click-to-Flip Area": "交换点击翻页区域",
"No chapters detected.": "未检测到章节。",
"Failed to parse the EPUB file.": "无法解析 EPUB 文件。",
"This book format is not supported.": "不支持此书籍格式。",
"Unable to fetch the translation. Please log in first and try again.": "无法获取翻译。请登录后重试。",
"Group": "分组"
}
@@ -53,20 +53,15 @@
"Hyphenation": "斷字",
"Identifier:": "識別碼",
"Import Books": "導入書籍",
"Invert Colors in Dark Mode": "深色主題下反色",
"Language:": "語言",
"Layout": "版面",
"Light Mode": "淺色主題",
"Line Height": "行高",
"Loading...": "載入中...",
"Loc. {{currentPage}} / {{totalPage}}": "位置 {{currentPage}} / {{totalPage}}",
"Logged in": "已登入",
"Logged in as {{userDisplayName}}": "{{userDisplayName}} 已登入",
"Match Case": "匹配大小寫",
"Match Diacritics": "匹配重音符號",
"Match Whole Words": "匹配整個單詞",
"Maximum Block Size": "內容最大寬度",
"Maximum Inline Size": "每欄最大寬度",
"Maximum Number of Columns": "分欄數",
"Minimum Font Size": "最小字號",
"Misc": "雜項",
@@ -76,7 +71,6 @@
"Notebook": "筆記本",
"Notes": "筆記",
"Open": "打開",
"Open Book": "打開書籍",
"Original Text": "原文",
"Page": "頁面",
"Paging Animation": "翻頁動畫",
@@ -150,5 +144,126 @@
"Book deleted: {{title}}": "書籍已刪除:{{title}}",
"Failed to delete book: {{title}}": "書籍刪除失敗:{{title}}",
"Check Updates on Start": "啟動時檢查更新",
"Insufficient storage quota": "雲存儲空間不足"
"Insufficient storage quota": "雲存儲空間不足",
"Font Weight": "字重",
"Line Spacing": "行間距",
"Word Spacing": "字間距",
"Letter Spacing": "字間距",
"Text Indent": "首行縮進",
"Paragraph Margin": "段間距",
"Override Book Layout": "覆蓋版面佈局",
"Untitled Group": "無標題組",
"Group Books": "分組書籍",
"Remove From Group": "從組中移除",
"Create New Group": "創建新組",
"Deselect Book": "取消選擇書籍",
"Download Book": "下載書籍",
"Deselect Group": "取消選擇組",
"Select Group": "選擇組",
"Keep Screen Awake": "保持屏幕常亮",
"Email address": "電子郵件地址",
"Your Password": "您的密碼",
"Your email address": "您的電子郵件地址",
"Your password": "您的密碼",
"Sign in": "登入",
"Signing in...": "正在登入...",
"Sign in with {{provider}}": "使用 {{provider}} 登入",
"Already have an account? Sign in": "已經有帳號?登入",
"Create a Password": "創建密碼",
"Sign up": "註冊",
"Signing up...": "正在註冊...",
"Dont have an account? Sign up": "沒有帳號?註冊",
"Check your email for the confirmation link": "檢查您的電子郵件以獲取確認連結",
"Signing in ...": "正在登入...",
"Send a magic link email": "發送魔法連結郵件",
"Check your email for the magic link": "檢查您的電子郵件以獲取魔法連結",
"Send reset password instructions": "發送重設密碼指示",
"Sending reset instructions ...": "正在發送重設密碼指示...",
"Forgot your password?": "忘記密碼?",
"Check your email for the password reset link": "檢查您的電子郵件以獲取密碼重設連結",
"New Password": "新密碼",
"Your new password": "您的新密碼",
"Update password": "更新密碼",
"Updating password ...": "正在更新密碼...",
"Your password has been updated": "您的密碼已更新",
"Phone number": "電話號碼",
"Your phone number": "您的電話號碼",
"Token": "令牌",
"Your OTP token": "您的 OTP 令牌",
"Verify token": "驗證令牌",
"Sign in with Google": "使用 Google 登入",
"Sign in with Apple": "使用 Apple 登入",
"Sign in with GitHub": "使用 GitHub 登入",
"Account": "帳戶",
"Cloud Storage": "雲端儲存空間",
"Failed to delete user. Please try again later.": "刪除使用者失敗。請稍後再試。",
"Unlimited Offline/Online Reading": "無限離線/線上閱讀",
"Unlimited Cloud Sync Devices": "無限雲端同步裝置",
"Essential Text-to-Speech Voices": "基本文字轉語音聲音",
"DeepL Free Access": "DeepL免費存取",
"Community Support": "社群支援",
"500 MB Cloud Sync Space": "500 MB雲端同步空間",
"Includes All Free Tier Benefits": "包含所有免費方案權益",
"AI Summaries": "AI摘要",
"AI Translations": "AI翻譯",
"Priority Support": "優先支援",
"DeepL Pro Access": "DeepL專業版存取",
"Expanded Text-to-Speech Voices": "擴展文字轉語音聲音",
"2000 MB Cloud Sync Space": "2000 MB雲端同步空間",
"Includes All Plus Tier Benefits": "包含所有Plus方案權益",
"Unlimited AI Summaries": "無限AI摘要",
"Unlimited AI Translations": "無限AI翻譯",
"Unlimited DeepL Pro Access": "無限DeepL專業版存取",
"Advanced AI Tools": "進階AI工具",
"Early Feature Access": "搶先體驗新功能",
"10 GB Cloud Sync Space": "10 GB雲端同步空間",
"Loading profile...": "載入個人資料中...",
"Features": "功能",
"Delete Account": "刪除帳戶",
"Delete Your Account?": "刪除您的帳戶?",
"This action cannot be undone. All your data in the cloud will be permanently deleted.": "此操作無法撤銷。您在雲端的所有資料將被永久刪除。",
"Delete Permanently": "永久刪除",
"Free Tier": "免費方案",
"Plus Tier": "Plus方案",
"Pro Tier": "專業方案",
"RTL Direction": "從右向左",
"Maximum Column Height": "最大列高",
"Maximum Column Width": "最大列寬",
"Continuous Scroll": "連續滾動",
"Fullscreen": "全螢幕",
"No supported files found. Supported formats: {{formats}}": "未找到支援的檔案。支援的格式:{{formats}}",
"Drop to Import Books": "拖放導入書籍",
"Custom": "自定義",
"All the world's a stage,\nAnd all the men and women merely players;\nThey have their exits and their entrances,\nAnd one man in his time plays many parts,\nHis acts being seven ages.\n\n— William Shakespeare": "世界是一個舞台,\n所有的男人和女人都只是演員:\n他們有出口,也有入口;\n一個人在他的時代扮演許多角​​色。 \n\n——威廉·莎士比亞",
"Custom Theme": "自定義主題",
"Theme Name": "主題名稱",
"Text Color": "文字顏色",
"Background Color": "背景顏色",
"Preview": "預覽",
"Contrast": "對比",
"Sunset": "日落",
"Double Border": "顯示邊框",
"Border Color": "邊框顏色",
"Border Frame": "頁面邊框",
"Show Header": "顯示頁眉",
"Show Footer": "顯示頁腳",
"Small": "小",
"Large": "大",
"Auto": "自動",
"Language": "語言",
"No annotations to export": "沒有要匯出的筆記",
"Author": "作者",
"Exported from Readest": "從 Readest 匯出",
"Highlights & Annotations": "高亮和筆記",
"Note": "筆記",
"Copied to clipboard": "已複製到剪貼板",
"Export Annotations": "匯出筆記",
"Auto Import on File Open": "打開文件時自動導入",
"LXGW WenKai GB Screen": "霞鶩文楷",
"Swap Click-to-Flip Area": "交換點擊翻頁區域",
"No chapters detected.": "未檢測到章節。",
"Failed to parse the EPUB file.": "無法解析 EPUB 文件。",
"This book format is not supported.": "不支援此書籍格式。",
"Unable to fetch the translation. Please log in first and try again.": "無法獲取翻譯。請先登入然後重試。",
"Group": "分組"
}
+147
View File
@@ -1,5 +1,152 @@
{
"releases": {
"0.9.30": {
"date": "2025-04-05",
"notes": [
"Added fixed storage quata when running the app in self-hosted mode",
"Link colors will only change when you override fonts",
"Added cache for native files for better performance"
]
},
"0.9.29": {
"date": "2025-04-02",
"notes": [
"Improved Login on Android without needing to rely on external Chrome browser",
"Local large book files now load more efficiently on Android",
"Balanced the load of online service between different types of users to keep things running smoothly for everyone"
]
},
"0.9.28": {
"date": "2025-03-30",
"notes": [
"Improved vertical reading mode with better support for Chinese punctuations",
"Fixed TXT file importing issue on desktop apps — TXT books now load reliably and display as expected",
"Improved annotation experience — highlighting tools are now properly dismissed when adding notes to avoid UI conflicts"
]
},
"0.9.27": {
"date": "2025-03-29",
"notes": [
"Added option to swap click-to-flip area and reset password",
"Added global shortcuts for full-text search",
"Added support for both R2 and S3 storage in cloud sync",
"Improved TTS with fewer unintended pauses, faster startup, and support for preferred voices",
"Various fixes for rendering styles and UI layout"
]
},
"0.9.26": {
"date": "2025-03-27",
"notes": [
"Support open book from file manager without importing",
"Add LXGW WenKai font in Serif fonts list",
"Various fixes on layout and styles on Windows and Android"
]
},
"0.9.25": {
"date": "2025-03-24",
"notes": [
"Support exporting annotations in markdown format",
"Support importing TXT files",
"Support setting reader language in the UI",
"Add bottom action bar on mobile platforms",
"Various fixes on layout settings and styles"
]
},
"0.9.23": {
"date": "2025-03-19",
"notes": [
"Add options to show/hide header and footer",
"Add responsive window size for popup footnotes",
"Fix theme color not applied on Safari browsers",
"Fix progress not updated to 100% when finished reading"
]
},
"0.9.22": {
"date": "2025-03-16",
"notes": [
"Add theme color editor for more customization",
"Add border frame for vertical layout",
"Fix layout glitches on macOS in scroll mode",
"Various fixes and enhancements on translator, footnote, and scrollbar"
]
},
"0.9.21": {
"date": "2025-03-10",
"notes": [
"Fix column height in vertical layout on mobile",
"Fix drag handle height not constant on mobile",
"Add fullscreen option on desktop",
"Add drag and drop to import books on desktop",
"Various fixes and enhancements on updater, footerbar and note"
]
},
"0.9.20": {
"date": "2025-03-10",
"notes": [
"Fix column height in vertical layout on mobile",
"Fix drag handle height not constant on mobile",
"Add fullscreen option on desktop",
"Add drag and drop to import books on desktop",
"Various fixes and enhancements on updater, footerbar and note"
]
},
"0.9.19": {
"date": "2025-03-07",
"notes": [
"Support custom CSS for Reader UI",
"Initial support of RTL layout for Arabic and Hebrew books",
"Various fixes and enhancements on layout and sync"
]
},
"0.9.18": {
"date": "2025-02-26",
"notes": [
"Add user profile page and option to delete account in the cloud",
"Fix TTS failed to start with invalid book language",
"Enhancements on iOS with modals and annotation tools",
"UX enhancements with modern highlights colors"
]
},
"0.9.17": {
"date": "2025-02-24",
"notes": [
"Add Arabic localization",
"Add Dockerfile to selfhost",
"Add safari-auth plugin for iOS OAuth",
"UX enhancements for mobile platforms with haptics feedback and pull-down dismissal"
]
},
"0.9.15": {
"date": "2025-02-21",
"notes": [
"Fix hardcoded font color from calibre",
"Fix scroll to current TOC item when toggling sidebar",
"Various fixes and enhancements on iOS platform"
]
},
"0.9.13": {
"date": "2025-02-19",
"notes": [
"Add option to keep screen awake when reading",
"Add shortcuts to notetaking UI",
"UX enhancements of grid view in mobile platforms"
]
},
"0.9.11": {
"date": "2025-02-14",
"notes": [
"Organize the library with customizable groups/folders",
"Alpha release for Android and iOS platforms",
"Various fixes and enhancements on Android and iOS platforms"
]
},
"0.9.10": {
"date": "2025-02-08",
"notes": [
"Add options to adjust paragraph margin, word spacing, letter spacing, text indent and font weight",
"Alpha release for Android and iOS platforms"
]
},
"0.9.9": {
"date": "2025-02-06",
"notes": [
@@ -0,0 +1,6 @@
pnpm tauri ios build --export-method app-store-connect
BUNDLE_DIR=src-tauri/gen/apple/build/arm64
IPA_BUNDLE=$BUNDLE_DIR/Readest.ipa
xcrun altool --upload-app --type ios --file $IPA_BUNDLE --apiKey $APPLE_API_KEY --apiIssuer $APPLE_API_ISSUER
+19 -19
View File
@@ -1,6 +1,6 @@
[package]
name = "Readest"
version = "0.2.1"
version = "0.2.2"
description = "Your online library"
authors = ["Bilingify LLC"]
license = ""
@@ -15,7 +15,7 @@ name = "readestlib"
crate-type = ["staticlib", "cdylib", "lib"]
[build-dependencies]
tauri-build = { version = "2.0.3", features = [] }
tauri-build = { version = "2.1.1", features = [] }
[dependencies]
serde_json = "1.0"
@@ -31,21 +31,21 @@ reqwest = { version = "0.12", default-features = false, features = [
"stream",
] }
# FIXME: remove the devtools feature in production
tauri = { version = "2.1.1", features = [ "protocol-asset", "devtools"] }
tauri-build = "2.0.3"
tauri-plugin-log = "2.0.2"
tauri-plugin-fs = "2.0.3"
tauri-plugin-dialog = "2.0.3"
tauri-plugin-os = "2.0.1"
tauri-plugin-http = "2.0.3"
tauri-plugin-devtools = "2.0.0"
tauri-plugin-shell = "2"
tauri-plugin-process = "2"
tauri = { version = "2.4.1", features = [ "protocol-asset", "devtools"] }
tauri-build = "2.1.1"
tauri-plugin-log = "2.3.1"
tauri-plugin-fs = "2.2.1"
tauri-plugin-dialog = "2.2.1"
tauri-plugin-os = "2.2.1"
tauri-plugin-http = "2.4.3"
tauri-plugin-shell = "2.2.1"
tauri-plugin-process = "2.2.1"
tauri-plugin-oauth = "2"
tauri-plugin-opener = "2.2.2"
tauri-plugin-deep-link = "2"
[patch.crates-io]
tauri = { path = "../../../packages/tauri/crates/tauri" }
tauri-plugin-opener = "2.2.6"
tauri-plugin-deep-link = "2.2.1"
tauri-plugin-sign-in-with-apple = "1.0.2"
tauri-plugin-haptics = "2.2.4"
tauri-plugin-native-bridge = { path = "./plugins/tauri-plugin-native-bridge" }
[target."cfg(target_os = \"macos\")".dependencies]
cocoa = "0.25"
@@ -54,7 +54,7 @@ rand = "0.8"
[target.'cfg(any(target_os = "macos", windows, target_os = "linux"))'.dependencies]
tauri-plugin-cli = "2"
tauri-plugin-single-instance = "2.2.0"
tauri-plugin-updater = "2"
tauri-plugin-window-state = "2.2.0"
tauri-plugin-single-instance = "2.2.3"
tauri-plugin-updater = "2.7.0"
tauri-plugin-window-state = "2.2.2"
font-enumeration = "0.9.0"
@@ -62,13 +62,21 @@
"core:window:allow-is-maximized",
"core:window:allow-start-dragging",
"core:window:allow-toggle-maximize",
"core:window:allow-set-fullscreen",
"log:default",
"shell:default",
"process:default",
"process:allow-exit",
"process:allow-restart",
"oauth:allow-start",
"oauth:allow-cancel",
"sign-in-with-apple:default",
"opener:default",
"haptics:allow-vibrate",
"haptics:allow-impact-feedback",
"haptics:allow-notification-feedback",
"haptics:allow-selection-feedback",
"native-bridge:default",
"deep-link:default"
]
}
@@ -0,0 +1,80 @@
import java.util.Properties
import java.io.FileInputStream
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("rust")
}
val tauriProperties = Properties().apply {
val propFile = file("tauri.properties")
if (propFile.exists()) {
propFile.inputStream().use { load(it) }
}
}
android {
compileSdk = 34
namespace = "com.bilingify.readest"
defaultConfig {
manifestPlaceholders["usesCleartextTraffic"] = "false"
applicationId = "com.bilingify.readest"
minSdk = 26
targetSdk = 34
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
}
signingConfigs {
create("release") {
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["password"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["password"] as String
}
}
buildTypes {
getByName("debug") {
manifestPlaceholders["usesCleartextTraffic"] = "true"
isDebuggable = true
isJniDebuggable = true
isMinifyEnabled = false
packaging { jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so")
jniLibs.keepDebugSymbols.add("*/x86/*.so")
jniLibs.keepDebugSymbols.add("*/x86_64/*.so")
}
}
getByName("release") {
signingConfig = signingConfigs.getByName("release")
}
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
buildConfig = true
}
}
rust {
rootDirRel = "../../../"
}
dependencies {
implementation("androidx.webkit:webkit:1.6.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.activity:activity-ktx:1.9.3")
implementation("com.google.android.material:material:1.8.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.4")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
}
apply(from = "tauri.build.gradle.kts")
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- AndroidTV support -->
<uses-feature android:name="android.software.leanback" android:required="false" />
<application
android:icon="@mipmap/ic_launcher"
android:largeHeap="true"
android:label="@string/app_name"
android:theme="@style/Theme.readest"
android:usesCleartextTraffic="${usesCleartextTraffic}">
<activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
android:launchMode="singleTask"
android:label="@string/main_activity_title"
android:name=".MainActivity"
android:exported="true">
<intent-filter android:label="oauth">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="readest" android:host="auth-callback" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!-- AndroidTV support -->
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<!-- DEEP LINK PLUGIN. AUTO-GENERATED. DO NOT REMOVE. -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="web.readest.com" />
</intent-filter>
<!-- DEEP LINK PLUGIN. AUTO-GENERATED. DO NOT REMOVE. -->
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
@@ -0,0 +1,51 @@
package com.bilingify.readest
import android.os.Build
import android.os.Bundle
import android.content.Intent
import android.net.Uri
import android.view.View
import android.view.WindowInsets
import android.view.WindowInsetsController
import androidx.activity.enableEdgeToEdge
import app.tauri.plugin.JSObject
import com.readest.native_bridge.NativeBridgePlugin
class MainActivity : TauriActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
hideSystemUI()
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
val uri = intent.data ?: return
if (uri.scheme == "readest" && uri.host == "auth-callback") {
val result = JSObject().apply {
put("redirectUrl", uri.toString())
}
NativeBridgePlugin.pendingInvoke?.resolve(result)
NativeBridgePlugin.pendingInvoke = null
}
}
private fun hideSystemUI() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.decorView.windowInsetsController?.let { controller ->
controller.hide(WindowInsets.Type.systemBars())
controller.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
} else {
@Suppress("DEPRECATION")
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
)
}
}
}
@@ -0,0 +1,9 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.readest" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>
</resources>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

@@ -0,0 +1,17 @@
/.vs
.DS_Store
.Thumbs.db
*.sublime*
.idea/
debug.log
package-lock.json
.vscode/settings.json
yarn.lock
/.tauri
/target
Cargo.lock
node_modules/
dist-js
dist
@@ -0,0 +1,19 @@
[package]
name = "tauri-plugin-native-bridge"
version = "0.1.0"
authors = [ "You" ]
description = "a bridge between tauri app and native OS functionality"
edition = "2021"
rust-version = "1.77.2"
exclude = ["/examples", "/dist-js", "/guest-js", "/node_modules"]
links = "tauri-plugin-native-bridge"
[dependencies]
tauri = { version = "2.3.1" }
serde = "1.0"
thiserror = "2"
schemars = "0.8"
[build-dependencies]
tauri-plugin = { version = "2.0.4", features = ["build"] }
schemars = "0.8"
@@ -0,0 +1 @@
# Tauri Plugin native-bridge
@@ -0,0 +1,2 @@
/build
/.tauri
@@ -0,0 +1,44 @@
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
}
android {
namespace = "com.readest.native_bridge"
compileSdk = 34
defaultConfig {
minSdk = 21
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.6.0")
implementation("androidx.browser:browser:1.8.0")
implementation("com.google.android.material:material:1.7.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
implementation(project(":tauri-android"))
}
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -0,0 +1,31 @@
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
google()
}
resolutionStrategy {
eachPlugin {
switch (requested.id.id) {
case "com.android.library":
useVersion("8.0.2")
break
case "org.jetbrains.kotlin.android":
useVersion("1.8.20")
break
}
}
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
google()
}
}
include ':tauri-android'
project(':tauri-android').projectDir = new File('./.tauri/tauri-api')
@@ -0,0 +1,24 @@
package com.readest.native_bridge
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.readest.native_bridge", appContext.packageName)
}
}
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>
@@ -0,0 +1,6 @@
package com.readest.native_bridge
import android.util.Log
class NativeBridge {
}
@@ -0,0 +1,77 @@
package com.readest.native_bridge
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.util.Log
import androidx.browser.customtabs.CustomTabsIntent
import app.tauri.annotation.Command
import app.tauri.annotation.InvokeArg
import app.tauri.annotation.TauriPlugin
import app.tauri.plugin.JSObject
import app.tauri.plugin.Plugin
import app.tauri.plugin.Invoke
import java.io.*
@InvokeArg
class AuthRequestArgs {
var authUrl: String? = null
}
@InvokeArg
class CopyURIRequestArgs {
var uri: String? = null
var dst: String? = null
}
@TauriPlugin
class NativeBridgePlugin(private val activity: Activity): Plugin(activity) {
private val implementation = NativeBridge()
private var redirectScheme = "readest"
private var redirectHost = "auth-callback"
companion object {
var pendingInvoke: Invoke? = null
}
@Command
fun auth_with_custom_tab(invoke: Invoke) {
val args = invoke.parseArgs(AuthRequestArgs::class.java)
val uri = Uri.parse(args.authUrl)
val customTabsIntent = CustomTabsIntent.Builder().build()
customTabsIntent.intent.flags = Intent.FLAG_ACTIVITY_NO_HISTORY
Log.d("NativeBridgePlugin", "Launching OAuth URL: ${args.authUrl}")
customTabsIntent.launchUrl(activity, uri)
pendingInvoke = invoke
}
@Command
fun copy_uri_to_path(invoke: Invoke) {
val args = invoke.parseArgs(CopyURIRequestArgs::class.java)
val ret = JSObject()
try {
val uri = Uri.parse(args.uri ?: "")
val dst = File(args.dst ?: "")
val inputStream = activity.contentResolver.openInputStream(uri)
if (inputStream != null) {
dst.outputStream().use { output ->
inputStream.use { input ->
input.copyTo(output)
}
}
ret.put("success", true)
} else {
ret.put("success", false)
ret.put("error", "Failed to open input stream from URI")
}
} catch (e: Exception) {
ret.put("success", false)
ret.put("error", e.message)
}
invoke.resolve(ret)
}
}
@@ -0,0 +1,17 @@
package com.readest.native_bridge
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
@@ -0,0 +1,12 @@
const COMMANDS: &[&str] = &[
"auth_with_safari",
"auth_with_custom_tab",
"copy_uri_to_path",
];
fn main() {
tauri_plugin::Builder::new(COMMANDS)
.android_path("android")
.ios_path("ios")
.build();
}
@@ -0,0 +1,10 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
Package.resolved
@@ -0,0 +1,32 @@
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "tauri-plugin-native-bridge",
platforms: [
.macOS(.v10_13),
.iOS(.v13),
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "tauri-plugin-native-bridge",
type: .static,
targets: ["tauri-plugin-native-bridge"]),
],
dependencies: [
.package(name: "Tauri", path: "../.tauri/tauri-api")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "tauri-plugin-native-bridge",
dependencies: [
.byName(name: "Tauri")
],
path: "Sources")
]
)
@@ -0,0 +1,3 @@
# Tauri Plugin native-bridge
A description of this package.
@@ -0,0 +1,55 @@
import AuthenticationServices
import SwiftRs
import Tauri
import UIKit
import WebKit
class SafariAuthRequestArgs: Decodable {
let authUrl: String
}
class NativeBridgePlugin: Plugin {
private var authSession: ASWebAuthenticationSession?
@objc public func auth_with_safari(_ invoke: Invoke) throws {
let args = try invoke.parseArgs(SafariAuthRequestArgs.self)
let authUrl = URL(string: args.authUrl)!
authSession = ASWebAuthenticationSession(url: authUrl, callbackURLScheme: "readest") {
[weak self] callbackURL, error in
guard let strongSelf = self else { return }
if let error = error {
Logger.error("Auth session error: \(error.localizedDescription)")
invoke.reject(error.localizedDescription)
return
}
if let callbackURL = callbackURL {
Logger.info("Auth session callback URL: \(callbackURL.absoluteString)")
strongSelf.authSession?.cancel()
strongSelf.authSession = nil
invoke.resolve(["redirectUrl": callbackURL.absoluteString])
}
}
if #available(iOS 13.0, *) {
authSession?.presentationContextProvider = self
}
let started = authSession?.start() ?? false
Logger.info("Auth session start result: \(started)")
}
}
@_cdecl("init_plugin_native_bridge")
func initPlugin() -> Plugin {
return NativeBridgePlugin()
}
@available(iOS 13.0, *)
extension NativeBridgePlugin: ASWebAuthenticationPresentationContextProviding {
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return UIApplication.shared.windows.first ?? UIWindow()
}
}
@@ -0,0 +1,8 @@
import XCTest
@testable import NativeBridgePlugin
final class NativeBridgePluginTests: XCTestCase {
func testNativeBridge() throws {
let plugin = NativeBridgePlugin()
}
}
@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-auth-with-custom-tab"
description = "Enables the auth_with_custom_tab command without any pre-configured scope."
commands.allow = ["auth_with_custom_tab"]
[[permission]]
identifier = "deny-auth-with-custom-tab"
description = "Denies the auth_with_custom_tab command without any pre-configured scope."
commands.deny = ["auth_with_custom_tab"]
@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-auth-with-safari"
description = "Enables the auth_with_safari command without any pre-configured scope."
commands.allow = ["auth_with_safari"]
[[permission]]
identifier = "deny-auth-with-safari"
description = "Denies the auth_with_safari command without any pre-configured scope."
commands.deny = ["auth_with_safari"]
@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!
"$schema" = "../../schemas/schema.json"
[[permission]]
identifier = "allow-copy-uri-to-path"
description = "Enables the copy_uri_to_path command without any pre-configured scope."
commands.allow = ["copy_uri_to_path"]
[[permission]]
identifier = "deny-copy-uri-to-path"
description = "Denies the copy_uri_to_path command without any pre-configured scope."
commands.deny = ["copy_uri_to_path"]
@@ -0,0 +1,97 @@
## Default Permission
Default permissions for the plugin
#### This default permission set includes the following:
- `allow-auth-with-safari`
- `allow-auth-with-custom-tab`
- `allow-copy-uri-to-path`
## Permission Table
<table>
<tr>
<th>Identifier</th>
<th>Description</th>
</tr>
<tr>
<td>
`native-bridge:allow-auth-with-custom-tab`
</td>
<td>
Enables the auth_with_custom_tab command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`native-bridge:deny-auth-with-custom-tab`
</td>
<td>
Denies the auth_with_custom_tab command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`native-bridge:allow-auth-with-safari`
</td>
<td>
Enables the auth_with_safari command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`native-bridge:deny-auth-with-safari`
</td>
<td>
Denies the auth_with_safari command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`native-bridge:allow-copy-uri-to-path`
</td>
<td>
Enables the copy_uri_to_path command without any pre-configured scope.
</td>
</tr>
<tr>
<td>
`native-bridge:deny-copy-uri-to-path`
</td>
<td>
Denies the copy_uri_to_path command without any pre-configured scope.
</td>
</tr>
</table>
@@ -0,0 +1,3 @@
[default]
description = "Default permissions for the plugin"
permissions = ["allow-auth-with-safari", "allow-auth-with-custom-tab", "allow-copy-uri-to-path"]
@@ -0,0 +1,342 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PermissionFile",
"description": "Permission file that can define a default permission, a set of permissions or a list of inlined permissions.",
"type": "object",
"properties": {
"default": {
"description": "The default permission set for the plugin",
"anyOf": [
{
"$ref": "#/definitions/DefaultPermission"
},
{
"type": "null"
}
]
},
"set": {
"description": "A list of permissions sets defined",
"type": "array",
"items": {
"$ref": "#/definitions/PermissionSet"
}
},
"permission": {
"description": "A list of inlined permissions",
"default": [],
"type": "array",
"items": {
"$ref": "#/definitions/Permission"
}
}
},
"definitions": {
"DefaultPermission": {
"description": "The default permission set of the plugin.\n\nWorks similarly to a permission with the \"default\" identifier.",
"type": "object",
"required": [
"permissions"
],
"properties": {
"version": {
"description": "The version of the permission.",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 1.0
},
"description": {
"description": "Human-readable description of what the permission does. Tauri convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
]
},
"permissions": {
"description": "All permissions this set contains.",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"PermissionSet": {
"description": "A set of direct permissions grouped together under a new name.",
"type": "object",
"required": [
"description",
"identifier",
"permissions"
],
"properties": {
"identifier": {
"description": "A unique identifier for the permission.",
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does.",
"type": "string"
},
"permissions": {
"description": "All permissions this set contains.",
"type": "array",
"items": {
"$ref": "#/definitions/PermissionKind"
}
}
}
},
"Permission": {
"description": "Descriptions of explicit privileges of commands.\n\nIt can enable commands to be accessible in the frontend of the application.\n\nIf the scope is defined it can be used to fine grain control the access of individual or multiple commands.",
"type": "object",
"required": [
"identifier"
],
"properties": {
"version": {
"description": "The version of the permission.",
"type": [
"integer",
"null"
],
"format": "uint64",
"minimum": 1.0
},
"identifier": {
"description": "A unique identifier for the permission.",
"type": "string"
},
"description": {
"description": "Human-readable description of what the permission does. Tauri internal convention is to use `<h4>` headings in markdown content for Tauri documentation generation purposes.",
"type": [
"string",
"null"
]
},
"commands": {
"description": "Allowed or denied commands when using this permission.",
"default": {
"allow": [],
"deny": []
},
"allOf": [
{
"$ref": "#/definitions/Commands"
}
]
},
"scope": {
"description": "Allowed or denied scoped when using this permission.",
"allOf": [
{
"$ref": "#/definitions/Scopes"
}
]
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"type": [
"array",
"null"
],
"items": {
"$ref": "#/definitions/Target"
}
}
}
},
"Commands": {
"description": "Allowed and denied commands inside a permission.\n\nIf two commands clash inside of `allow` and `deny`, it should be denied by default.",
"type": "object",
"properties": {
"allow": {
"description": "Allowed command.",
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"deny": {
"description": "Denied command, which takes priority.",
"default": [],
"type": "array",
"items": {
"type": "string"
}
}
}
},
"Scopes": {
"description": "An argument for fine grained behavior control of Tauri commands.\n\nIt can be of any serde serializable type and is used to allow or prevent certain actions inside a Tauri command. The configured scope is passed to the command and will be enforced by the command implementation.\n\n## Example\n\n```json { \"allow\": [{ \"path\": \"$HOME/**\" }], \"deny\": [{ \"path\": \"$HOME/secret.txt\" }] } ```",
"type": "object",
"properties": {
"allow": {
"description": "Data that defines what is allowed by the scope.",
"type": [
"array",
"null"
],
"items": {
"$ref": "#/definitions/Value"
}
},
"deny": {
"description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.",
"type": [
"array",
"null"
],
"items": {
"$ref": "#/definitions/Value"
}
}
}
},
"Value": {
"description": "All supported ACL values.",
"anyOf": [
{
"description": "Represents a null JSON value.",
"type": "null"
},
{
"description": "Represents a [`bool`].",
"type": "boolean"
},
{
"description": "Represents a valid ACL [`Number`].",
"allOf": [
{
"$ref": "#/definitions/Number"
}
]
},
{
"description": "Represents a [`String`].",
"type": "string"
},
{
"description": "Represents a list of other [`Value`]s.",
"type": "array",
"items": {
"$ref": "#/definitions/Value"
}
},
{
"description": "Represents a map of [`String`] keys to [`Value`]s.",
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/Value"
}
}
]
},
"Number": {
"description": "A valid ACL number.",
"anyOf": [
{
"description": "Represents an [`i64`].",
"type": "integer",
"format": "int64"
},
{
"description": "Represents a [`f64`].",
"type": "number",
"format": "double"
}
]
},
"Target": {
"description": "Platform target.",
"oneOf": [
{
"description": "MacOS.",
"type": "string",
"enum": [
"macOS"
]
},
{
"description": "Windows.",
"type": "string",
"enum": [
"windows"
]
},
{
"description": "Linux.",
"type": "string",
"enum": [
"linux"
]
},
{
"description": "Android.",
"type": "string",
"enum": [
"android"
]
},
{
"description": "iOS.",
"type": "string",
"enum": [
"iOS"
]
}
]
},
"PermissionKind": {
"type": "string",
"oneOf": [
{
"description": "Enables the auth_with_custom_tab command without any pre-configured scope.",
"type": "string",
"const": "allow-auth-with-custom-tab",
"markdownDescription": "Enables the auth_with_custom_tab command without any pre-configured scope."
},
{
"description": "Denies the auth_with_custom_tab command without any pre-configured scope.",
"type": "string",
"const": "deny-auth-with-custom-tab",
"markdownDescription": "Denies the auth_with_custom_tab command without any pre-configured scope."
},
{
"description": "Enables the auth_with_safari command without any pre-configured scope.",
"type": "string",
"const": "allow-auth-with-safari",
"markdownDescription": "Enables the auth_with_safari command without any pre-configured scope."
},
{
"description": "Denies the auth_with_safari command without any pre-configured scope.",
"type": "string",
"const": "deny-auth-with-safari",
"markdownDescription": "Denies the auth_with_safari command without any pre-configured scope."
},
{
"description": "Enables the copy_uri_to_path command without any pre-configured scope.",
"type": "string",
"const": "allow-copy-uri-to-path",
"markdownDescription": "Enables the copy_uri_to_path command without any pre-configured scope."
},
{
"description": "Denies the copy_uri_to_path command without any pre-configured scope.",
"type": "string",
"const": "deny-copy-uri-to-path",
"markdownDescription": "Denies the copy_uri_to_path command without any pre-configured scope."
},
{
"description": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-auth-with-safari`\n- `allow-auth-with-custom-tab`\n- `allow-copy-uri-to-path`",
"type": "string",
"const": "default",
"markdownDescription": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-auth-with-safari`\n- `allow-auth-with-custom-tab`\n- `allow-copy-uri-to-path`"
}
]
}
}
}
@@ -0,0 +1,29 @@
use tauri::{command, AppHandle, Runtime};
use crate::models::*;
use crate::NativeBridgeExt;
use crate::Result;
#[command]
pub(crate) async fn auth_with_safari<R: Runtime>(
app: AppHandle<R>,
payload: AuthRequest,
) -> Result<AuthResponse> {
app.native_bridge().auth_with_safari(payload)
}
#[command]
pub(crate) async fn auth_with_custom_tab<R: Runtime>(
app: AppHandle<R>,
payload: AuthRequest,
) -> Result<AuthResponse> {
app.native_bridge().auth_with_custom_tab(payload)
}
#[command]
pub(crate) async fn copy_uri_to_path<R: Runtime>(
app: AppHandle<R>,
payload: CopyURIRequest,
) -> Result<CopyURIResponse> {
app.native_bridge().copy_uri_to_path(payload)
}
@@ -0,0 +1,28 @@
use serde::de::DeserializeOwned;
use tauri::{plugin::PluginApi, AppHandle, Runtime};
use crate::models::*;
pub fn init<R: Runtime, C: DeserializeOwned>(
app: &AppHandle<R>,
_api: PluginApi<R, C>,
) -> crate::Result<NativeBridge<R>> {
Ok(NativeBridge(app.clone()))
}
/// Access to the native-bridge APIs.
pub struct NativeBridge<R: Runtime>(AppHandle<R>);
impl<R: Runtime> NativeBridge<R> {
pub fn auth_with_safari(&self, _payload: AuthRequest) -> crate::Result<AuthResponse> {
Err(crate::Error::UnsupportedPlatformError)
}
pub fn auth_with_custom_tab(&self, _payload: AuthRequest) -> crate::Result<AuthResponse> {
Err(crate::Error::UnsupportedPlatformError)
}
pub fn copy_uri_to_path(&self, _payload: CopyURIRequest) -> crate::Result<CopyURIResponse> {
Err(crate::Error::UnsupportedPlatformError)
}
}
@@ -0,0 +1,25 @@
use serde::{ser::Serializer, Serialize};
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Unsupported platform for this plugin")]
UnsupportedPlatformError,
#[error("Native bridge error: {0}")]
NativeBridgeError(String),
#[error(transparent)]
Io(#[from] std::io::Error),
#[cfg(mobile)]
#[error(transparent)]
PluginInvoke(#[from] tauri::plugin::mobile::PluginInvokeError),
}
impl Serialize for Error {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.to_string().as_ref())
}
}
@@ -0,0 +1,53 @@
use tauri::{
plugin::{Builder, TauriPlugin},
Manager, Runtime,
};
pub use models::*;
#[cfg(desktop)]
mod desktop;
#[cfg(mobile)]
mod mobile;
mod commands;
mod error;
mod models;
mod platform;
pub use error::{Error, Result};
#[cfg(desktop)]
use desktop::NativeBridge;
#[cfg(mobile)]
use mobile::NativeBridge;
/// Extensions to [`tauri::App`], [`tauri::AppHandle`] and [`tauri::Window`] to access the native-bridge APIs.
pub trait NativeBridgeExt<R: Runtime> {
fn native_bridge(&self) -> &NativeBridge<R>;
}
impl<R: Runtime, T: Manager<R>> crate::NativeBridgeExt<R> for T {
fn native_bridge(&self) -> &NativeBridge<R> {
self.state::<NativeBridge<R>>().inner()
}
}
/// Initializes the plugin.
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("native-bridge")
.invoke_handler(tauri::generate_handler![
commands::auth_with_safari,
commands::auth_with_custom_tab,
commands::copy_uri_to_path,
])
.setup(|app, api| {
#[cfg(mobile)]
let native_bridge = mobile::init(app, api)?;
#[cfg(desktop)]
let native_bridge = desktop::init(app, api)?;
app.manage(native_bridge);
Ok(())
})
.build()
}
@@ -0,0 +1,49 @@
use serde::de::DeserializeOwned;
use tauri::{
plugin::{PluginApi, PluginHandle},
AppHandle, Runtime,
};
use crate::models::*;
#[cfg(target_os = "ios")]
tauri::ios_plugin_binding!(init_plugin_native_bridge);
// initializes the Kotlin or Swift plugin classes
pub fn init<R: Runtime, C: DeserializeOwned>(
_app: &AppHandle<R>,
api: PluginApi<R, C>,
) -> crate::Result<NativeBridge<R>> {
#[cfg(target_os = "android")]
let handle = api.register_android_plugin("com.readest.native_bridge", "NativeBridgePlugin")?;
#[cfg(target_os = "ios")]
let handle = api.register_ios_plugin(init_plugin_native_bridge)?;
Ok(NativeBridge(handle))
}
/// Access to the native-bridge APIs.
pub struct NativeBridge<R: Runtime>(PluginHandle<R>);
impl<R: Runtime> NativeBridge<R> {
pub fn auth_with_safari(&self, payload: AuthRequest) -> crate::Result<AuthResponse> {
self.0
.run_mobile_plugin("auth_with_safari", payload)
.map_err(Into::into)
}
}
impl<R: Runtime> NativeBridge<R> {
pub fn auth_with_custom_tab(&self, payload: AuthRequest) -> crate::Result<AuthResponse> {
self.0
.run_mobile_plugin("auth_with_custom_tab", payload)
.map_err(Into::into)
}
}
impl<R: Runtime> NativeBridge<R> {
pub fn copy_uri_to_path(&self, payload: CopyURIRequest) -> crate::Result<CopyURIResponse> {
self.0
.run_mobile_plugin("copy_uri_to_path", payload)
.map_err(Into::into)
}
}
@@ -0,0 +1,27 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthRequest {
pub auth_url: String,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthResponse {
pub redirect_url: String,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CopyURIRequest {
pub uri: String,
pub dst: String,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CopyURIResponse {
pub success: bool,
pub error: Option<String>,
}
@@ -0,0 +1,2 @@
#[cfg(target_os = "macos")]
pub mod macos;
+94 -48
View File
@@ -9,23 +9,24 @@ extern crate objc;
#[cfg(target_os = "macos")]
mod menu;
#[cfg(target_os = "macos")]
mod traffic_light_plugin;
mod transfer_file;
use transfer_file::{download_file, upload_file};
mod traffic_light;
#[cfg(target_os = "macos")]
use traffic_light::set_traffic_lights;
#[cfg(target_os = "macos")]
use tauri::TitleBarStyle;
use std::path::PathBuf;
use tauri::{command, Window};
use tauri::{AppHandle, Emitter, Manager, Url};
use tauri::{WebviewUrl, WebviewWindowBuilder};
use tauri_plugin_fs::FsExt;
use tauri_plugin_oauth::start;
#[cfg(desktop)]
use tauri::Listener;
use std::path::PathBuf;
#[cfg(desktop)]
use tauri::{AppHandle, Listener, Manager, Url};
#[cfg(desktop)]
use tauri_plugin_fs::FsExt;
mod transfer_file;
use tauri::{command, Emitter, WebviewUrl, WebviewWindowBuilder, Window};
use tauri_plugin_oauth::start;
use transfer_file::{download_file, upload_file};
#[cfg(desktop)]
fn allow_file_in_scopes(app: &AppHandle, files: Vec<PathBuf>) {
@@ -45,6 +46,31 @@ fn allow_file_in_scopes(app: &AppHandle, files: Vec<PathBuf>) {
}
}
#[cfg(desktop)]
fn get_files_from_argv(argv: Vec<String>) -> Vec<PathBuf> {
let mut files = Vec::new();
// NOTICE: `args` may include URL protocol (`your-app-protocol://`)
// or arguments (`--`) if your app supports them.
// files may also be passed as `file://path/to/file`
for (_, maybe_file) in argv.iter().enumerate().skip(1) {
// skip flags like -f or --flag
if maybe_file.starts_with("-") {
continue;
}
// handle `file://` path urls and skip other urls
if let Ok(url) = Url::parse(maybe_file) {
if let Ok(path) = url.to_file_path() {
files.push(path);
} else {
files.push(PathBuf::from(maybe_file))
}
} else {
files.push(PathBuf::from(maybe_file))
}
}
files
}
#[cfg(desktop)]
fn set_window_open_with_files(app: &AppHandle, files: Vec<PathBuf>) {
let files = files
@@ -62,6 +88,15 @@ fn set_window_open_with_files(app: &AppHandle, files: Vec<PathBuf>) {
}
}
#[cfg(desktop)]
fn set_rounded_window(app: &AppHandle, rounded: bool) {
let window = app.get_webview_window("main").unwrap();
let script = format!("window.IS_ROUNDED = {};", rounded);
if let Err(e) = window.eval(&script) {
eprintln!("Failed to set IS_ROUNDED variable: {}", e);
}
}
#[command]
async fn start_server(window: Window) -> Result<u16, String> {
start(move |url| {
@@ -78,12 +113,13 @@ async fn list_fonts() -> Result<Vec<String>, String> {
let font_collection = font_enumeration::Collection::new().unwrap();
let mut fonts = Vec::new();
for font in font_collection.all() {
fonts.push(font.font_name.clone());
fonts.push(font.family_name.clone());
}
Ok(fonts)
}
#[derive(Clone, serde::Serialize)]
#[allow(dead_code)]
struct Payload {
args: Vec<String>,
cwd: String,
@@ -98,6 +134,8 @@ pub fn run() {
start_server,
download_file,
upload_file,
#[cfg(target_os = "macos")]
set_traffic_lights,
#[cfg(desktop)]
list_fonts
])
@@ -106,6 +144,7 @@ pub fn run() {
.plugin(tauri_plugin_http::init())
.plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_native_bridge::init())
.plugin(tauri_plugin_fs::init());
#[cfg(desktop)]
@@ -114,6 +153,10 @@ pub fn run() {
.get_webview_window("main")
.expect("no main window")
.set_focus();
let files = get_files_from_argv(argv.clone());
if !files.is_empty() {
allow_file_in_scopes(app, files.clone());
}
app.emit("single-instance", Payload { args: argv, cwd })
.unwrap();
}));
@@ -127,32 +170,19 @@ pub fn run() {
let builder = builder.plugin(tauri_plugin_window_state::Builder::default().build());
#[cfg(target_os = "macos")]
let builder = builder.plugin(traffic_light_plugin::init());
let builder = builder.plugin(traffic_light::init());
#[cfg(target_os = "ios")]
let builder = builder.plugin(tauri_plugin_sign_in_with_apple::init());
#[cfg(any(target_os = "ios", target_os = "android"))]
let builder = builder.plugin(tauri_plugin_haptics::init());
builder
.setup(|#[allow(unused_variables)] app| {
#[cfg(desktop)]
{
let mut files = Vec::new();
// NOTICE: `args` may include URL protocol (`your-app-protocol://`)
// or arguments (`--`) if your app supports them.
// files may also be passed as `file://path/to/file`
for maybe_file in std::env::args().skip(1) {
// skip flags like -f or --flag
if maybe_file.starts_with("-") {
continue;
}
// handle `file://` path urls and skip other urls
if let Ok(url) = Url::parse(&maybe_file) {
if let Ok(path) = url.to_file_path() {
files.push(path);
} else {
files.push(PathBuf::from(maybe_file))
}
} else {
files.push(PathBuf::from(maybe_file))
}
}
let files = get_files_from_argv(std::env::args().collect());
if !files.is_empty() {
let app_handle = app.handle().clone();
allow_file_in_scopes(&app_handle, files.clone());
@@ -172,6 +202,12 @@ pub fn run() {
app_handle.get_webview_window("main").unwrap()
.eval("window.__READEST_CLI_ACCESS = true; window.__READEST_UPDATER_ACCESS = true;")
.expect("Failed to set cli access config");
set_rounded_window(&app_handle, true);
#[cfg(target_os = "windows")]
if tauri_plugin_os::version() <= tauri_plugin_os::Version::from_string("10.0.19045") {
set_rounded_window(&app_handle, false);
}
});
}
@@ -181,14 +217,11 @@ pub fn run() {
app.deep_link().register_all()?;
}
#[cfg(desktop)]
if cfg!(debug_assertions) {
app.handle().plugin(
tauri_plugin_log::Builder::default()
.level(log::LevelFilter::Info)
.build(),
)?;
}
app.handle().plugin(
tauri_plugin_log::Builder::default()
.level(log::LevelFilter::Info)
.build(),
)?;
let win_builder = WebviewWindowBuilder::new(app, "main", WebviewUrl::default());
@@ -204,12 +237,25 @@ pub fn run() {
.title("");
#[cfg(all(not(target_os = "macos"), desktop))]
let win_builder = win_builder
.decorations(false)
.transparent(true)
.visible(false)
.shadow(true)
.title("Readest");
let win_builder = {
let mut win_builder = win_builder
.decorations(false)
.transparent(true)
.visible(false)
.title("Readest");
if cfg!(target_os = "windows") {
if tauri_plugin_os::version() <= tauri_plugin_os::Version::from_string("10.0.19045") {
win_builder = win_builder.shadow(false);
} else {
win_builder = win_builder.shadow(true);
}
} else {
win_builder = win_builder.shadow(true);
}
win_builder
};
win_builder.build().unwrap();
// let win = win_builder.build().unwrap();
@@ -1,20 +1,21 @@
use objc::{msg_send, sel, sel_impl};
use rand::{distributions::Alphanumeric, Rng};
use tauri::Emitter;
use tauri::{
command,
plugin::{Builder, TauriPlugin},
Runtime, Window,
}; // 0.8
Emitter, Runtime, Window,
};
const WINDOW_CONTROL_PAD_X: f64 = 10.0;
const WINDOW_CONTROL_PAD_Y: f64 = 20.0;
static mut WINDOW_CONTROL_PAD_X: f64 = 10.0;
static mut WINDOW_CONTROL_PAD_Y: f64 = 22.0;
static mut TRAFFIC_LIGHTS_VISIBLE: bool = true;
struct UnsafeWindowHandle(*mut std::ffi::c_void);
unsafe impl Send for UnsafeWindowHandle {}
unsafe impl Sync for UnsafeWindowHandle {}
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("traffic_light_positioner")
Builder::new("traffic_light")
.on_window_ready(|window| {
#[cfg(target_os = "macos")]
setup_traffic_light_positioner(window.clone());
@@ -30,7 +31,24 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
}
#[cfg(target_os = "macos")]
fn position_traffic_lights(ns_window_handle: UnsafeWindowHandle, x: f64, y: f64) {
#[command]
pub fn set_traffic_lights(window: Window, visible: bool, x: f64, y: f64) {
unsafe {
TRAFFIC_LIGHTS_VISIBLE = visible;
WINDOW_CONTROL_PAD_X = x;
WINDOW_CONTROL_PAD_Y = y;
position_traffic_lights(
UnsafeWindowHandle(window.ns_window().expect("Failed to create window handle")),
TRAFFIC_LIGHTS_VISIBLE,
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
);
}
}
#[cfg(target_os = "macos")]
fn position_traffic_lights(ns_window_handle: UnsafeWindowHandle, visible: bool, x: f64, y: f64) {
use cocoa::appkit::{NSView, NSWindow, NSWindowButton};
use cocoa::foundation::NSRect;
let ns_window = ns_window_handle.0 as cocoa::base::id;
@@ -45,7 +63,10 @@ fn position_traffic_lights(ns_window_handle: UnsafeWindowHandle, x: f64, y: f64)
let close_rect: NSRect = msg_send![close, frame];
let button_height = close_rect.size.height;
let title_bar_frame_height = button_height + y;
let mut title_bar_frame_height = button_height + y;
if !visible {
title_bar_frame_height = 0.0;
}
let mut title_bar_rect = NSView::frame(title_bar_container_view);
title_bar_rect.size.height = title_bar_frame_height;
title_bar_rect.origin.y = NSView::frame(ns_window).size.height - title_bar_frame_height;
@@ -77,11 +98,14 @@ pub fn setup_traffic_light_positioner<R: Runtime>(window: Window<R>) {
use std::ffi::c_void;
// Do the initial positioning
position_traffic_lights(
UnsafeWindowHandle(window.ns_window().expect("Failed to create window handle")),
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
);
unsafe {
position_traffic_lights(
UnsafeWindowHandle(window.ns_window().expect("Failed to create window handle")),
TRAFFIC_LIGHTS_VISIBLE,
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
);
}
// Ensure they stay in place while resizing the window.
fn with_window_state<R: Runtime, F: FnOnce(&mut WindowState<R>) -> T, T>(
@@ -127,6 +151,7 @@ pub fn setup_traffic_light_positioner<R: Runtime>(window: Window<R>) {
#[cfg(target_os = "macos")]
position_traffic_lights(
UnsafeWindowHandle(id as *mut std::ffi::c_void),
TRAFFIC_LIGHTS_VISIBLE,
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
);
@@ -258,6 +283,7 @@ pub fn setup_traffic_light_positioner<R: Runtime>(window: Window<R>) {
let id = state.window.ns_window().expect("Failed to emit event") as id;
position_traffic_lights(
UnsafeWindowHandle(id as *mut std::ffi::c_void),
TRAFFIC_LIGHTS_VISIBLE,
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
);
+6 -3
View File
@@ -14,11 +14,11 @@
"windows": [],
"security": {
"csp": {
"default-src": "'self' 'unsafe-inline' blob: customprotocol: asset: http://asset.localhost ipc: http://ipc.localhost",
"connect-src": "'self' blob: asset: http://asset.localhost ipc: http://ipc.localhost https://*.sentry.io https://*.posthog.com https://*.deepl.com https://*.wikipedia.org https://*.wiktionary.org https://*.supabase.co https://*.readest.com wss://speech.platform.bing.com https://*.cloudflarestorage.com",
"default-src": "'self' 'unsafe-inline' blob: data: customprotocol: asset: http://asset.localhost ipc: http://ipc.localhost",
"connect-src": "'self' blob: data: asset: http://asset.localhost ipc: http://ipc.localhost https://*.sentry.io https://*.posthog.com https://*.deepl.com https://*.wikipedia.org https://*.wiktionary.org https://*.supabase.co https://*.readest.com wss://speech.platform.bing.com https://*.cloudflarestorage.com",
"img-src": "'self' blob: data: asset: http://asset.localhost https://*",
"style-src": "'self' 'unsafe-inline' blob: asset: http://asset.localhost https://cdn.jsdelivr.net https://fonts.googleapis.com",
"font-src": "'self' data: asset: http://asset.localhost tauri: https://fonts.gstatic.com https://db.onlinewebfonts.com https://cdn.jsdelivr.net",
"font-src": "'self' blob: data: asset: http://asset.localhost tauri: https://fonts.gstatic.com https://db.onlinewebfonts.com https://cdn.jsdelivr.net",
"frame-src": "'self' blob: asset: http://asset.localhost",
"script-src": "'self' 'unsafe-inline' 'unsafe-eval' blob: asset: http://asset.localhost https://*.sentry.io https://*.posthog.com"
},
@@ -59,6 +59,9 @@
"android": {
"minSdkVersion": 26
},
"iOS": {
"developmentTeam": "J5W48D69VR"
},
"fileAssociations": [
{
"name": "epub",
@@ -16,9 +16,27 @@ export default function AuthCallback() {
const accessToken = params.get('access_token');
const refreshToken = params.get('refresh_token');
const type = params.get('type');
const next = params.get('next') ?? '/';
const error = params.get('error');
const errorDescription = params.get('error_description');
const errorCode = params.get('error_code');
handleAuthCallback({ accessToken, refreshToken, next, login, navigate: router.push });
handleAuthCallback({
accessToken,
refreshToken,
type,
next,
error,
errorCode,
errorDescription,
login,
navigate: router.push,
});
return null;
return (
<div className='fixed inset-0 z-50 flex items-center justify-center'>
<span className='loading loading-infinity loading-xl w-20'></span>
</div>
);
}

Some files were not shown because too many files have changed in this diff Show More