├── .github
├── FUNDING.yml
└── workflows
│ ├── build.yaml
│ ├── dart.yaml
│ └── release.yaml
├── .gitignore
├── .gitmodules
├── .isar-cargo.lock
├── .metadata
├── .mimir-cargo.lock
├── .ndk-version
├── .patrol.env
├── .ruby-version
├── .run
├── debug.run.xml
├── release.run.xml
└── screenshots.run.xml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Gemfile
├── Gemfile.lock
├── LICENSE
├── README.md
├── RELEASING.md
├── SECURITY.md
├── analysis_options.yaml
├── android
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── app
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── io
│ │ │ │ └── flutter
│ │ │ │ └── app
│ │ │ │ └── FlutterMultiDexApplication.java
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── maelchiotti
│ │ │ │ └── localmaterialnotes
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-hdpi
│ │ │ ├── android12splash.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ ├── ic_launcher_monochrome.png
│ │ │ └── splash.png
│ │ │ ├── drawable-mdpi
│ │ │ ├── android12splash.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ ├── ic_launcher_monochrome.png
│ │ │ └── splash.png
│ │ │ ├── drawable-night-hdpi
│ │ │ ├── android12splash.png
│ │ │ └── splash.png
│ │ │ ├── drawable-night-mdpi
│ │ │ ├── android12splash.png
│ │ │ └── splash.png
│ │ │ ├── drawable-night-v21
│ │ │ ├── background.png
│ │ │ └── launch_background.xml
│ │ │ ├── drawable-night-xhdpi
│ │ │ ├── android12splash.png
│ │ │ └── splash.png
│ │ │ ├── drawable-night-xxhdpi
│ │ │ ├── android12splash.png
│ │ │ └── splash.png
│ │ │ ├── drawable-night-xxxhdpi
│ │ │ ├── android12splash.png
│ │ │ └── splash.png
│ │ │ ├── drawable-night
│ │ │ ├── background.png
│ │ │ └── launch_background.xml
│ │ │ ├── drawable-v21
│ │ │ ├── background.png
│ │ │ └── launch_background.xml
│ │ │ ├── drawable-xhdpi
│ │ │ ├── android12splash.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ ├── ic_launcher_monochrome.png
│ │ │ └── splash.png
│ │ │ ├── drawable-xxhdpi
│ │ │ ├── android12splash.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ ├── ic_launcher_monochrome.png
│ │ │ └── splash.png
│ │ │ ├── drawable-xxxhdpi
│ │ │ ├── android12splash.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ ├── ic_launcher_monochrome.png
│ │ │ └── splash.png
│ │ │ ├── drawable
│ │ │ ├── background.png
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ └── ic_launcher.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_checklist.png
│ │ │ ├── ic_format_paint.png
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_markdown.png
│ │ │ └── ic_text_fields.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_checklist.png
│ │ │ ├── ic_format_paint.png
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_markdown.png
│ │ │ └── ic_text_fields.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── raw
│ │ │ └── localmaterialnotes_keep.xml
│ │ │ ├── values-night-v31
│ │ │ └── styles.xml
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ ├── values-v31
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── fonts
│ ├── Barlow
│ │ ├── Barlow-Black.ttf
│ │ ├── Barlow-BlackItalic.ttf
│ │ ├── Barlow-Bold.ttf
│ │ ├── Barlow-BoldItalic.ttf
│ │ ├── Barlow-ExtraBold.ttf
│ │ ├── Barlow-ExtraBoldItalic.ttf
│ │ ├── Barlow-ExtraLight.ttf
│ │ ├── Barlow-ExtraLightItalic.ttf
│ │ ├── Barlow-Italic.ttf
│ │ ├── Barlow-Light.ttf
│ │ ├── Barlow-LightItalic.ttf
│ │ ├── Barlow-Medium.ttf
│ │ ├── Barlow-MediumItalic.ttf
│ │ ├── Barlow-Regular.ttf
│ │ ├── Barlow-SemiBold.ttf
│ │ ├── Barlow-SemiBoldItalic.ttf
│ │ ├── Barlow-Thin.ttf
│ │ └── Barlow-ThinItalic.ttf
│ ├── Comic_Sans_MS
│ │ └── ComicSansMS.ttf
│ ├── Dancing_Script
│ │ └── DancingScript-VariableFont_wght.ttf
│ ├── JetBrains_Mono
│ │ ├── JetBrainsMono-Italic-VariableFont_wght.ttf
│ │ └── JetBrainsMono-VariableFont_wght.ttf
│ ├── Merriweather
│ │ ├── Merriweather-Black.ttf
│ │ ├── Merriweather-BlackItalic.ttf
│ │ ├── Merriweather-Bold.ttf
│ │ ├── Merriweather-BoldItalic.ttf
│ │ ├── Merriweather-Italic.ttf
│ │ ├── Merriweather-Light.ttf
│ │ ├── Merriweather-LightItalic.ttf
│ │ └── Merriweather-Regular.ttf
│ ├── Montserrat
│ │ ├── Montserrat-Italic-VariableFont_wght.ttf
│ │ └── Montserrat-VariableFont_wght.ttf
│ ├── Noto_Sans
│ │ ├── NotoSans-Italic-VariableFont_wdth,wght.ttf
│ │ └── NotoSans-VariableFont_wdth,wght.ttf
│ ├── Open_Sans
│ │ ├── OpenSans-Italic-VariableFont_wdth,wght.ttf
│ │ └── OpenSans-VariableFont_wdth,wght.ttf
│ ├── Playfair_Display
│ │ ├── PlayfairDisplay-Italic-VariableFont_wght.ttf
│ │ └── PlayfairDisplay-VariableFont_wght.ttf
│ ├── Raleway
│ │ ├── Raleway-Italic-VariableFont_wght.ttf
│ │ └── Raleway-VariableFont_wght.ttf
│ ├── Roboto_Mono
│ │ ├── RobotoMono-Italic-VariableFont_wght.ttf
│ │ └── RobotoMono-VariableFont_wght.ttf
│ └── Ubuntu
│ │ ├── Ubuntu-Bold.ttf
│ │ ├── Ubuntu-BoldItalic.ttf
│ │ ├── Ubuntu-Italic.ttf
│ │ ├── Ubuntu-Light.ttf
│ │ ├── Ubuntu-LightItalic.ttf
│ │ ├── Ubuntu-Medium.ttf
│ │ ├── Ubuntu-MediumItalic.ttf
│ │ └── Ubuntu-Regular.ttf
└── icons
│ ├── icon.png
│ ├── icon.svg
│ ├── icon_android_12.png
│ ├── icon_foreground.png
│ ├── icon_foreground.svg
│ └── icon_foreground_monochrome.png
├── build.yaml
├── docs
├── badges
│ ├── fdroid.png
│ ├── fdroid.psd
│ ├── github.png
│ ├── github.psd
│ ├── google_play.png
│ ├── google_play.psd
│ ├── izzyondroid.png
│ ├── izzyondroid.psd
│ ├── obtainium.png
│ └── obtainium.psd
├── data
│ ├── export.json
│ ├── export_1000_notes.json
│ └── export_old.json
├── external_imports
│ ├── .run
│ │ ├── DNotes.run.xml
│ │ └── Samsung Notes.run.xml
│ ├── EXTERNAL_IMPORTS.md
│ ├── apps
│ │ ├── dnotes.py
│ │ └── samsung_notes.py
│ ├── converter.py
│ ├── inputs
│ │ ├── d_notes.zip
│ │ └── samsung_notes.zip
│ ├── outputs
│ │ └── .gitkeep
│ └── requirements.txt
├── github
│ ├── social_preview.png
│ └── social_preview.psd
└── google_play
│ ├── banner.png
│ ├── banner.psd
│ ├── changelogs_max_length.txt
│ └── icon_google_play.png
├── fastlane
├── Appfile
├── Fastfile
└── metadata
│ └── android
│ ├── cs-CZ
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
│ ├── de-DE
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
│ ├── en-US
│ ├── changelogs
│ │ ├── 100.txt
│ │ ├── 110.txt
│ │ ├── 120.txt
│ │ ├── 130.txt
│ │ ├── 140.txt
│ │ ├── 150.txt
│ │ ├── 160.txt
│ │ ├── 170.txt
│ │ ├── 180.txt
│ │ ├── 190.txt
│ │ ├── 200.txt
│ │ ├── 210.txt
│ │ ├── 220.txt
│ │ ├── 230.txt
│ │ ├── 240.txt
│ │ ├── 250.txt
│ │ ├── 260.txt
│ │ ├── 280.txt
│ │ ├── 70.txt
│ │ └── 90.txt
│ ├── full_description.txt
│ ├── full_description.yaml
│ ├── images
│ │ ├── featureGraphic.png
│ │ ├── icon.png
│ │ └── phoneScreenshots
│ │ │ ├── 1_en-US.png
│ │ │ ├── 2_en-US.png
│ │ │ ├── 3_en-US.png
│ │ │ ├── 4_en-US.png
│ │ │ ├── 5_en-US.png
│ │ │ ├── 6_en-US.png
│ │ │ ├── 7_en-US.png
│ │ │ └── 8_en-US.png
│ ├── short_description.txt
│ └── title.txt
│ ├── es-ES
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
│ ├── fr-FR
│ ├── changelogs
│ │ ├── 100.txt
│ │ ├── 110.txt
│ │ ├── 120.txt
│ │ ├── 130.txt
│ │ ├── 140.txt
│ │ ├── 150.txt
│ │ ├── 160.txt
│ │ ├── 170.txt
│ │ ├── 180.txt
│ │ ├── 190.txt
│ │ ├── 200.txt
│ │ ├── 210.txt
│ │ ├── 220.txt
│ │ ├── 230.txt
│ │ ├── 240.txt
│ │ ├── 250.txt
│ │ ├── 260.txt
│ │ ├── 280.txt
│ │ ├── 70.txt
│ │ └── 90.txt
│ ├── full_description.txt
│ ├── full_description.yaml
│ ├── short_description.txt
│ └── title.txt
│ ├── hi-IN
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
│ ├── id
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
│ ├── it-IT
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
│ ├── pl-PL
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
│ ├── pt-PT
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
│ ├── ru-RU
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
│ ├── tr-TR
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
│ ├── zh-CN
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
│ └── zh-TW
│ ├── full_description.txt
│ ├── short_description.txt
│ └── title.txt
├── flutter_launcher_icons.yaml
├── flutter_native_splash.yaml
├── l10n.yaml
├── lib
├── app.dart
├── common
│ ├── actions
│ │ ├── labels
│ │ │ ├── add.dart
│ │ │ ├── delete.dart
│ │ │ ├── edit.dart
│ │ │ ├── lock.dart
│ │ │ ├── pin.dart
│ │ │ ├── select.dart
│ │ │ └── visible.dart
│ │ └── notes
│ │ │ ├── about.dart
│ │ │ ├── add.dart
│ │ │ ├── archive.dart
│ │ │ ├── copy.dart
│ │ │ ├── delete.dart
│ │ │ ├── labels.dart
│ │ │ ├── lock.dart
│ │ │ ├── pin.dart
│ │ │ ├── pop.dart
│ │ │ ├── restore.dart
│ │ │ ├── select.dart
│ │ │ ├── share.dart
│ │ │ └── unarchive.dart
│ ├── constants
│ │ ├── constants.dart
│ │ ├── environment.dart
│ │ ├── labels.dart
│ │ ├── notes.dart
│ │ ├── paddings.dart
│ │ ├── separators.dart
│ │ └── sizes.dart
│ ├── dialogs
│ │ └── confirmation_dialog.dart
│ ├── enums
│ │ ├── mime_type.dart
│ │ ├── supported_language.dart
│ │ └── swipe_direction.dart
│ ├── extensions
│ │ ├── build_context_extension.dart
│ │ ├── color_extension.dart
│ │ ├── date_time_extensions.dart
│ │ ├── iterable_extension.dart
│ │ ├── list_extension.dart
│ │ ├── locale_extension.dart
│ │ ├── string_extension.dart
│ │ └── text_style_extension.dart
│ ├── files
│ │ ├── encryption_utils.dart
│ │ └── files_utils.dart
│ ├── logs
│ │ ├── app_logger.dart
│ │ └── filters
│ │ │ ├── default_filter.dart
│ │ │ └── release_filter.dart
│ ├── navigation
│ │ ├── app_bars
│ │ │ ├── basic_app_bar.dart
│ │ │ ├── labels
│ │ │ │ └── labels_app_bar.dart
│ │ │ ├── notes
│ │ │ │ ├── editor_app_bar.dart
│ │ │ │ └── notes_app_bar.dart
│ │ │ └── selection
│ │ │ │ ├── labels_selection_app_bar.dart
│ │ │ │ └── notes_selection_app_bar.dart
│ │ ├── enums
│ │ │ ├── editor
│ │ │ │ ├── editor_archived_menu_option.dart
│ │ │ │ ├── editor_available_menu_option.dart
│ │ │ │ └── editor_deleted_menu_option.dart
│ │ │ ├── labels
│ │ │ │ └── selection_labels_menu_option.dart
│ │ │ └── notes
│ │ │ │ ├── selection_archived_menu_option.dart
│ │ │ │ ├── selection_available_menu_option.dart
│ │ │ │ └── selection_deleted_menu_option.dart
│ │ ├── side_navigation.dart
│ │ └── top_navigation.dart
│ ├── preferences
│ │ ├── enums
│ │ │ ├── confirmations.dart
│ │ │ ├── font.dart
│ │ │ ├── layout.dart
│ │ │ ├── sort_method.dart
│ │ │ ├── swipe_actions
│ │ │ │ ├── archived_swipe_action.dart
│ │ │ │ ├── available_swipe_action.dart
│ │ │ │ ├── deleted_swipe_action.dart
│ │ │ │ └── label_swipe_action.dart
│ │ │ └── toolbar_style.dart
│ │ ├── preference_key.dart
│ │ ├── preferences_wrapper.dart
│ │ └── watched_preferences.dart
│ ├── system_utils.dart
│ ├── types.dart
│ ├── ui
│ │ ├── snack_bar_utils.dart
│ │ └── theme_utils.dart
│ └── widgets
│ │ ├── asset.dart
│ │ ├── labels
│ │ ├── label_badge.dart
│ │ ├── label_dismissible.dart
│ │ └── label_placeholder_badge.dart
│ │ ├── notes
│ │ ├── dismissible
│ │ │ ├── archived_dismissible.dart
│ │ │ ├── available_dismissible.dart
│ │ │ └── deleted_dismissible.dart
│ │ ├── note_tile.dart
│ │ ├── note_tile_labels_list.dart
│ │ └── notes_list.dart
│ │ └── placeholders
│ │ ├── empty_placeholder.dart
│ │ ├── error_placeholder.dart
│ │ └── loading_placeholder.dart
├── l10n
│ └── translations
│ │ ├── app_cs.arb
│ │ ├── app_de.arb
│ │ ├── app_en.arb
│ │ ├── app_es.arb
│ │ ├── app_fr.arb
│ │ ├── app_hi.arb
│ │ ├── app_it.arb
│ │ ├── app_pl.arb
│ │ ├── app_pt.arb
│ │ ├── app_ru.arb
│ │ ├── app_tr.arb
│ │ ├── app_zh-Hant.arb
│ │ ├── app_zh-TW.arb
│ │ └── app_zh.arb
├── main.dart
├── models
│ ├── deprecated
│ │ └── note.dart
│ ├── label
│ │ └── label.dart
│ └── note
│ │ ├── index
│ │ └── note_index.dart
│ │ ├── note.dart
│ │ ├── note_status.dart
│ │ └── types
│ │ ├── checklist_note.dart
│ │ ├── markdown_note.dart
│ │ ├── note_type.dart
│ │ ├── plain_text_note.dart
│ │ └── rich_text_note.dart
├── navigation
│ ├── navigation_routes.dart
│ └── router.dart
├── pages
│ ├── archives
│ │ └── archives_page.dart
│ ├── bin
│ │ ├── bin_page.dart
│ │ └── widgets
│ │ │ └── empty_bin_fab.dart
│ ├── editor
│ │ ├── dialogs
│ │ │ ├── labels_selection_dialog.dart
│ │ │ └── toolbar_link_dialog.dart
│ │ ├── editor_page.dart
│ │ ├── sheets
│ │ │ └── about_sheet.dart
│ │ └── widgets
│ │ │ ├── editor_labels_list.dart
│ │ │ ├── editors
│ │ │ ├── checklist_editor.dart
│ │ │ ├── markdown_editor.dart
│ │ │ ├── plain_text_editor.dart
│ │ │ ├── rich_text_editor.dart
│ │ │ └── title_editor.dart
│ │ │ └── toolbar
│ │ │ ├── color_toolbar_button.dart
│ │ │ ├── heading_toolbar_button.dart
│ │ │ ├── horizontal_rule_toolbar_button.dart
│ │ │ ├── indentation_toolbar_button.dart
│ │ │ ├── link_toolbar_button.dart
│ │ │ ├── toolbar.dart
│ │ │ └── toolbar_button.dart
│ ├── labels
│ │ ├── dialogs
│ │ │ └── label_dialog.dart
│ │ ├── enums
│ │ │ ├── label_tile_menu_option.dart
│ │ │ └── labels_filter.dart
│ │ ├── labels_page.dart
│ │ └── widgets
│ │ │ ├── add_label_fab.dart
│ │ │ ├── label_tile.dart
│ │ │ └── labels_filters.dart
│ ├── lock
│ │ └── lock_page.dart
│ ├── notes
│ │ ├── notes_page.dart
│ │ └── widgets
│ │ │ └── add_note_fab.dart
│ └── settings
│ │ ├── dialogs
│ │ ├── auto_export_password_dialog.dart
│ │ └── manual_export_dialog.dart
│ │ ├── pages
│ │ ├── settings_about_page.dart
│ │ ├── settings_accessibility_page.dart
│ │ ├── settings_appearance_page.dart
│ │ ├── settings_backup_page.dart
│ │ ├── settings_behavior_page.dart
│ │ ├── settings_editor_page.dart
│ │ ├── settings_help_page.dart
│ │ ├── settings_labels_page.dart
│ │ ├── settings_notes_tiles_page.dart
│ │ ├── settings_notes_types_page.dart
│ │ └── settings_security_page.dart
│ │ ├── settings_main_page.dart
│ │ └── widgets
│ │ ├── encrypt_password_form.dart
│ │ ├── password_field.dart
│ │ └── setting_value_text.dart
├── providers
│ ├── labels
│ │ ├── labels
│ │ │ └── labels_provider.dart
│ │ ├── labels_list
│ │ │ └── labels_list_provider.dart
│ │ └── labels_navigation
│ │ │ └── labels_navigation_provider.dart
│ ├── notes
│ │ └── notes_provider.dart
│ ├── notifiers
│ │ ├── confirm_exit_notifier.dart
│ │ ├── current_note_notifier.dart
│ │ ├── lock_notifier.dart
│ │ ├── notifiers.dart
│ │ └── selection_mode_notifier.dart
│ └── preferences
│ │ └── preferences_provider.dart
└── services
│ ├── backup
│ ├── auto_backup_service.dart
│ └── backup_service.dart
│ ├── bin
│ └── bin_service.dart
│ ├── database_service.dart
│ ├── labels
│ └── labels_service.dart
│ ├── migration
│ └── migration_service.dart
│ └── notes
│ ├── notes_index_service.dart
│ └── notes_service.dart
├── makefile
├── pubspec.lock
├── pubspec.yaml
├── rust-toolchain.toml
└── scripts
├── generate_full_description.py
├── isar
├── fdroid_build_isar.sh
└── fdroid_update_isar.sh
└── mimir
├── fdroid_build_mimir.sh
└── fdroid_update_mimir.sh
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: maelchiotti
2 | custom: https://www.paypal.me/maelchiotti
--------------------------------------------------------------------------------
/.github/workflows/build.yaml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on: pull_request
4 |
5 | permissions:
6 | contents: write
7 |
8 | jobs:
9 | build_android:
10 | name: Android
11 | environment: build
12 | runs-on: ubuntu-latest
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v4
16 | - name: Setup Java
17 | uses: actions/setup-java@v4
18 | with:
19 | java-version: '17'
20 | distribution: 'temurin'
21 | - name: Setup Flutter
22 | uses: subosito/flutter-action@v2
23 | with:
24 | channel: 'stable'
25 | flutter-version-file: pubspec.yaml
26 | - name: Add keystore
27 | run: echo "${{ secrets.ANDROID_KEYSTORE }}" | base64 -d > android/localmaterialnotes_keystore.jks
28 | - name: Add key properties
29 | run: echo "${{ secrets.ANDROID_KEY_PROPERTIES }}" > android/key.properties
30 | - name: Build app
31 | run: |
32 | dart run build_runner build
33 | flutter gen-l10n
34 | flutter build apk --release
35 | - name: Archive APK
36 | uses: actions/upload-artifact@v4
37 | with:
38 | name: LocalMaterialNotes
39 | path: build/app/outputs/flutter-apk/app-release.apk
--------------------------------------------------------------------------------
/.github/workflows/dart.yaml:
--------------------------------------------------------------------------------
1 | name: Dart
2 |
3 | on: push
4 |
5 | permissions: read-all
6 |
7 | jobs:
8 | lint:
9 | name: Lint
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v4
14 | - name: Setup Flutter
15 | uses: subosito/flutter-action@v2
16 | with:
17 | channel: 'stable'
18 | flutter-version-file: pubspec.yaml
19 | - name: Analyze
20 | run: |
21 | dart run build_runner build
22 | flutter gen-l10n
23 | flutter pub get
24 | dart analyze --fatal-infos
25 |
26 | format:
27 | name: Format
28 | runs-on: ubuntu-latest
29 | steps:
30 | - name: Checkout
31 | uses: actions/checkout@v4
32 | - name: Setup Flutter
33 | uses: subosito/flutter-action@v2
34 | with:
35 | channel: 'stable'
36 | flutter-version-file: pubspec.yaml
37 | - name: Format
38 | run: dart format -l 120 --set-exit-if-changed .
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | **/doc/api/
26 | **/ios/Flutter/.last_build_id
27 | .dart_tool/
28 | .flutter-plugins
29 | .flutter-plugins-dependencies
30 | .packages
31 | .pub-cache/
32 | .pub/
33 | /build/
34 |
35 | # Symbolication related
36 | app.*.symbols
37 |
38 | # Obfuscation related
39 | app.*.map.json
40 |
41 | # Android Studio will place build artifacts here
42 | /android/app/debug
43 | /android/app/profile
44 | /android/app/release
45 |
46 | # Distribution
47 | *.iss
48 | /dist/
49 |
50 | # l10n
51 | lib/l10n/untranslated.txt
52 |
53 | # fastlane
54 | fastlane/localmaterialnotes_fastlane-supply_key.json
55 | fastlane/README.md
56 | fastlane/report.xml
57 |
58 | # Generated files
59 | *.g.dart
60 |
61 | # External imports
62 | docs/external_imports/outputs/*.json
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule ".isar"]
2 | path = .isar
3 | url = https://github.com/isar-community/isar
4 | [submodule ".mimir"]
5 | path = .mimir
6 | url = https://github.com/GregoryConrad/mimir
7 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: "2e9cb0aa71a386a91f73f7088d115c0d96654829"
8 | channel: "stable"
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829
17 | base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829
18 | - platform: web
19 | create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829
20 | base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829
21 |
22 | # User provided section
23 |
24 | # List of Local paths (relative to this file) that should be
25 | # ignored by the migrate tool.
26 | #
27 | # Files that are not part of the templates will be ignored by default.
28 | unmanaged_files:
29 | - 'lib/main.dart'
30 | - 'ios/Runner.xcodeproj/project.pbxproj'
31 |
--------------------------------------------------------------------------------
/.ndk-version:
--------------------------------------------------------------------------------
1 | r26d
--------------------------------------------------------------------------------
/.patrol.env:
--------------------------------------------------------------------------------
1 | INTEGRATION_TEST=true
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | 3.3.1
--------------------------------------------------------------------------------
/.run/debug.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.run/release.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.run/screenshots.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | ## Localization
4 |
5 | All localizations are hosted on [Crowdin](https://crowdin.com/project/localmaterialnotes).
6 |
7 | 
8 |
9 | ### Improve an already existing localization
10 |
11 | Logged in with your Crowdin account, open the [Crowdin project](https://crowdin.com/project/localmaterialnotes), select the language you want to improve and use the "Join" button.
12 |
13 | ### Add a new language
14 |
15 | Create an [issue](https://github.com/maelchiotti/LocalMaterialNotes/issues) mentioning which language you would like to be added.
16 |
17 | ## External imports scripts
18 |
19 | To submit a script that converts an export from an other application to the format used by Material Notes, either open an issue and provide the script, or open a pull request that add your script to the [external_imports](docs/external_imports) directory (in that case, please name the file after the application).
20 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "fastlane"
--------------------------------------------------------------------------------
/RELEASING.md:
--------------------------------------------------------------------------------
1 | # Releasing
2 |
3 | ## Checklist
4 |
5 | ### Upgrades, versioning and code generation
6 |
7 | - [ ] Upgrade Flutter and Dart versions
8 | - [ ] Bump application version
9 | - [ ] Bump dependencies versions
10 |
11 | ### Changelogs
12 |
13 | - [ ] Update [CHANGELOG.md](CHANGELOG.md)
14 | - [ ] Update fastlane changelogs
15 |
16 | ### Descriptions
17 |
18 | - [ ] Update the [README.md](README.md) description
19 | - [ ] Update fastlane descriptions
20 |
21 | ### Localizations
22 |
23 | - [ ] Update the localizations from [Crowdin](https://crowdin.com/project/localmaterialnotes)
24 | - [ ] Update the [supported languages](lib/common/enums/supported_language.dart)
25 | - [ ] Update the [README.md](README.md) list of supported languages
26 |
27 | ### Screenshots
28 |
29 | - [ ] Update screenshot [notes](lib/common/constants/notes.dart) and [labels](lib/common/constants/labels.dart)
30 | - [ ] Update fastlane screenshots
31 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | You should always update to the latest version to receive the most recent security updates.
6 |
7 | ## Reporting a Vulnerability
8 |
9 | Any vulnerability can be reported in the [Security Advisories](https://github.com/maelchiotti/LocalMaterialNotes/security/advisories) section.
10 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:flutter_lints/flutter.yaml
2 |
3 | formatter:
4 | page_width: 120
5 |
6 | analyzer:
7 | exclude:
8 | - '**.g.dart'
9 | plugins:
10 | - custom_lint
11 | language:
12 | strict-inference: true
13 |
14 | linter:
15 | rules:
16 | - public_member_api_docs
17 | - prefer_relative_imports
18 | - always_put_control_body_on_new_line
19 | - curly_braces_in_flow_control_structures
20 | - unawaited_futures
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 | app/.cxx
9 |
10 | # Remember to never publicly share your keystore.
11 | # See https://flutter.dev/to/reference-keystore
12 | key.properties
13 | **/*.keystore
14 | **/*.jks
15 |
--------------------------------------------------------------------------------
/android/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "fastlane"
--------------------------------------------------------------------------------
/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | -keep class androidx.lifecycle.DefaultLifecycleObserver
2 |
3 | -dontwarn com.google.errorprone.annotations.CanIgnoreReturnValue
4 | -dontwarn com.google.errorprone.annotations.CheckReturnValue
5 | -dontwarn com.google.errorprone.annotations.Immutable
6 | -dontwarn com.google.errorprone.annotations.RestrictedApi
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java:
--------------------------------------------------------------------------------
1 | // Generated file.
2 | //
3 | // If you wish to remove Flutter's multidex support, delete this entire file.
4 | //
5 | // Modifications to this file should be done in a copy under a different name
6 | // as this file may be regenerated.
7 |
8 | package io.flutter.app;
9 |
10 | import android.app.Application;
11 | import android.content.Context;
12 | import androidx.annotation.CallSuper;
13 | import androidx.multidex.MultiDex;
14 |
15 | /**
16 | * Extension of {@link android.app.Application}, adding multidex support.
17 | */
18 | public class FlutterMultiDexApplication extends Application {
19 | @Override
20 | @CallSuper
21 | protected void attachBaseContext(Context base) {
22 | super.attachBaseContext(base);
23 | MultiDex.install(this);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/maelchiotti/localmaterialnotes/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.maelchiotti.localmaterialnotes
2 |
3 | import io.flutter.embedding.android.FlutterFragmentActivity
4 |
5 | class MainActivity : FlutterFragmentActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-hdpi/android12splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-hdpi/android12splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-hdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-hdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-hdpi/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-hdpi/splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-mdpi/android12splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-mdpi/android12splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-mdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-mdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-mdpi/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-mdpi/splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-hdpi/android12splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night-hdpi/android12splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-hdpi/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night-hdpi/splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-mdpi/android12splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night-mdpi/android12splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-mdpi/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night-mdpi/splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-v21/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night-v21/background.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 | -
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-xhdpi/android12splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night-xhdpi/android12splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-xhdpi/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night-xhdpi/splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-xxhdpi/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night-xxhdpi/splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night-xxxhdpi/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night-xxxhdpi/splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-night/background.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-night/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 | -
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-v21/background.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 | -
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xhdpi/android12splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xhdpi/android12splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xhdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xhdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xhdpi/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xhdpi/splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxhdpi/android12splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xxhdpi/android12splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxhdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xxhdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxhdpi/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xxhdpi/splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxxhdpi/android12splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xxxhdpi/android12splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_monochrome.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxxhdpi/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable-xxxhdpi/splash.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/drawable/background.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 | -
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_checklist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-hdpi/ic_checklist.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_format_paint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-hdpi/ic_format_paint.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_markdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-hdpi/ic_markdown.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_text_fields.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-hdpi/ic_text_fields.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_checklist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-mdpi/ic_checklist.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_format_paint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-mdpi/ic_format_paint.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_markdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-mdpi/ic_markdown.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_text_fields.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-mdpi/ic_text_fields.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/raw/localmaterialnotes_keep.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night-v31/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
19 |
22 |
23 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values-v31/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
18 |
21 |
22 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2278e9
4 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | allprojects {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 | }
7 |
8 | rootProject.buildDir = "../build"
9 | subprojects {
10 | project.buildDir = "${rootProject.buildDir}/${project.name}"
11 | }
12 | subprojects {
13 | project.evaluationDependsOn(":app")
14 | }
15 |
16 | tasks.register("clean", Delete) {
17 | delete rootProject.buildDir
18 | }
19 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
6 | distributionSha256Sum=bb09982fdf52718e4c7b25023d10df6d35a5fff969860bdf5a5bd27a3ab27a9e
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | def flutterSdkPath = {
3 | def properties = new Properties()
4 | file("local.properties").withInputStream { properties.load(it) }
5 | def flutterSdkPath = properties.getProperty("flutter.sdk")
6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7 | return flutterSdkPath
8 | }()
9 |
10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
11 |
12 | repositories {
13 | google()
14 | mavenCentral()
15 | gradlePluginPortal()
16 | }
17 | }
18 |
19 | plugins {
20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
21 | id "com.android.application" version "8.1.0" apply false
22 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false
23 | }
24 |
25 | include ":app"
26 |
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-Black.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-BlackItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-BlackItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-Bold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-BoldItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-ExtraBold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-ExtraBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-ExtraBoldItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-ExtraLight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-ExtraLight.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-ExtraLightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-ExtraLightItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-Italic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-Light.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-LightItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-Medium.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-MediumItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-MediumItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-Regular.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-SemiBold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-SemiBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-SemiBoldItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-Thin.ttf
--------------------------------------------------------------------------------
/assets/fonts/Barlow/Barlow-ThinItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Barlow/Barlow-ThinItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Comic_Sans_MS/ComicSansMS.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Comic_Sans_MS/ComicSansMS.ttf
--------------------------------------------------------------------------------
/assets/fonts/Dancing_Script/DancingScript-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Dancing_Script/DancingScript-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/JetBrains_Mono/JetBrainsMono-Italic-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/JetBrains_Mono/JetBrainsMono-Italic-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/JetBrains_Mono/JetBrainsMono-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/JetBrains_Mono/JetBrainsMono-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Merriweather/Merriweather-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Merriweather/Merriweather-Black.ttf
--------------------------------------------------------------------------------
/assets/fonts/Merriweather/Merriweather-BlackItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Merriweather/Merriweather-BlackItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Merriweather/Merriweather-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Merriweather/Merriweather-Bold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Merriweather/Merriweather-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Merriweather/Merriweather-BoldItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Merriweather/Merriweather-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Merriweather/Merriweather-Italic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Merriweather/Merriweather-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Merriweather/Merriweather-Light.ttf
--------------------------------------------------------------------------------
/assets/fonts/Merriweather/Merriweather-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Merriweather/Merriweather-LightItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Merriweather/Merriweather-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Merriweather/Merriweather-Regular.ttf
--------------------------------------------------------------------------------
/assets/fonts/Montserrat/Montserrat-Italic-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Montserrat/Montserrat-Italic-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Montserrat/Montserrat-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Montserrat/Montserrat-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Noto_Sans/NotoSans-Italic-VariableFont_wdth,wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Noto_Sans/NotoSans-Italic-VariableFont_wdth,wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Noto_Sans/NotoSans-VariableFont_wdth,wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Noto_Sans/NotoSans-VariableFont_wdth,wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Open_Sans/OpenSans-Italic-VariableFont_wdth,wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Open_Sans/OpenSans-Italic-VariableFont_wdth,wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Open_Sans/OpenSans-VariableFont_wdth,wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Open_Sans/OpenSans-VariableFont_wdth,wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Playfair_Display/PlayfairDisplay-Italic-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Playfair_Display/PlayfairDisplay-Italic-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Playfair_Display/PlayfairDisplay-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Playfair_Display/PlayfairDisplay-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Raleway/Raleway-Italic-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Raleway/Raleway-Italic-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Raleway/Raleway-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Raleway/Raleway-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Roboto_Mono/RobotoMono-Italic-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Roboto_Mono/RobotoMono-Italic-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Roboto_Mono/RobotoMono-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Roboto_Mono/RobotoMono-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/assets/fonts/Ubuntu/Ubuntu-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Ubuntu/Ubuntu-Bold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Ubuntu/Ubuntu-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Ubuntu/Ubuntu-BoldItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Ubuntu/Ubuntu-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Ubuntu/Ubuntu-Italic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Ubuntu/Ubuntu-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Ubuntu/Ubuntu-Light.ttf
--------------------------------------------------------------------------------
/assets/fonts/Ubuntu/Ubuntu-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Ubuntu/Ubuntu-LightItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Ubuntu/Ubuntu-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Ubuntu/Ubuntu-Medium.ttf
--------------------------------------------------------------------------------
/assets/fonts/Ubuntu/Ubuntu-MediumItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Ubuntu/Ubuntu-MediumItalic.ttf
--------------------------------------------------------------------------------
/assets/fonts/Ubuntu/Ubuntu-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/fonts/Ubuntu/Ubuntu-Regular.ttf
--------------------------------------------------------------------------------
/assets/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/icons/icon.png
--------------------------------------------------------------------------------
/assets/icons/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/assets/icons/icon_android_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/icons/icon_android_12.png
--------------------------------------------------------------------------------
/assets/icons/icon_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/icons/icon_foreground.png
--------------------------------------------------------------------------------
/assets/icons/icon_foreground.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 | Layer 1
9 |
10 |
11 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/assets/icons/icon_foreground_monochrome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/assets/icons/icon_foreground_monochrome.png
--------------------------------------------------------------------------------
/build.yaml:
--------------------------------------------------------------------------------
1 | targets:
2 | $default:
3 | builders:
4 | json_serializable:
5 | options:
6 | explicit_to_json: true
7 | field_rename: snake
--------------------------------------------------------------------------------
/docs/badges/fdroid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/badges/fdroid.png
--------------------------------------------------------------------------------
/docs/badges/fdroid.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/badges/fdroid.psd
--------------------------------------------------------------------------------
/docs/badges/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/badges/github.png
--------------------------------------------------------------------------------
/docs/badges/github.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/badges/github.psd
--------------------------------------------------------------------------------
/docs/badges/google_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/badges/google_play.png
--------------------------------------------------------------------------------
/docs/badges/google_play.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/badges/google_play.psd
--------------------------------------------------------------------------------
/docs/badges/izzyondroid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/badges/izzyondroid.png
--------------------------------------------------------------------------------
/docs/badges/izzyondroid.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/badges/izzyondroid.psd
--------------------------------------------------------------------------------
/docs/badges/obtainium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/badges/obtainium.png
--------------------------------------------------------------------------------
/docs/badges/obtainium.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/badges/obtainium.psd
--------------------------------------------------------------------------------
/docs/data/export.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.5.0",
3 | "encrypted": false,
4 | "notes": [
5 | {
6 | "deleted": false,
7 | "pinned": true,
8 | "created_time": "2024-08-03T09:26:47.455199",
9 | "edited_time": "2024-08-03T09:26:47.455211",
10 | "title": "Welcome to Material Notes!",
11 | "content": "[{\"insert\":\"Simple, local, material design notes\\n\\n\"}]"
12 | }
13 | ]
14 | }
--------------------------------------------------------------------------------
/docs/data/export_old.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "deleted": false,
4 | "pinned": true,
5 | "created_time": "2024-08-03T09:26:47.455199",
6 | "edited_time": "2024-08-03T09:26:47.455211",
7 | "title": "Welcome to Material Notes!",
8 | "content": "[{\"insert\":\"Simple, local, material design notes\\n\\n\"}]"
9 | }
10 | ]
--------------------------------------------------------------------------------
/docs/external_imports/.run/DNotes.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/external_imports/.run/Samsung Notes.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/external_imports/EXTERNAL_IMPORTS.md:
--------------------------------------------------------------------------------
1 | # External imports
2 |
3 | Python scripts are available to convert export from other note-taking apps to the format used by Material Notes.
4 |
5 | ## Supported apps
6 |
7 | ### D Notes
8 |
9 | The file to use is the ZIP file exported from the settings.
10 |
11 | ### Samsung Notes
12 |
13 | The file to use is a ZIP file that you need to create yourself, from the notes you exported as text using multi-selection in the notes list. The proprietary format that can be exported from the settings cannot be read, so this is the only solution.
14 |
15 | ## Setup
16 |
17 | 1. Install [Python](https://www.python.org/downloads/)
18 | 2. Clone or download this repository
19 | 3. Open a terminal in the [docs/external_imports](/docs/external_imports) directory
20 | 4. Install the dependencies: `py -m pip install -r requirements.txt`
21 |
22 | ## Run
23 |
24 | Run `py path/to/converter.py -a app_name -i /path/to/backup_file.zip -o /path/to/export_file.json` to convert the backup file.
25 |
26 | Run `py path/to/converter.py -h` to see how to use the arguments.
27 |
28 | Ignore the [inputs](/docs/external_imports/inputs) and [outputs](/docs/external_imports/outputs) folder, they are only used for testing.
29 |
--------------------------------------------------------------------------------
/docs/external_imports/apps/samsung_notes.py:
--------------------------------------------------------------------------------
1 | from zipfile import ZipFile
2 | import json
3 | from datetime import datetime
4 | import re
5 |
6 | date_time_regex = "%y%m%d_%H%M%S"
7 |
8 |
9 | def convert(input_file):
10 | notes = []
11 |
12 | try:
13 | with ZipFile(input_file, "r") as zip_file:
14 | for filename in zip_file.namelist():
15 | if not filename.endswith(".txt"):
16 | continue
17 |
18 | title_split = filename.split("_")
19 | if not len(filename) > 0:
20 | print(f"Failed to parse the title of {filename}")
21 | continue
22 |
23 | date_time_match = re.search(r"\d{6}_\d{6}", filename)
24 | if not date_time_match:
25 | print(f"Failed to parse the date and time of {filename}")
26 | continue
27 | date_time = datetime.strptime(date_time_match[0], date_time_regex)
28 |
29 | title = title_split[0]
30 | content = zip_file.read(filename).decode()
31 | created_time = date_time
32 | edited_time = date_time
33 | pinned = False
34 | deleted = False
35 |
36 | if not content.endswith("\n"):
37 | content += "\n"
38 |
39 | note = {
40 | "title": title,
41 | "content": json.dumps(
42 | [{"insert": content}],
43 | ensure_ascii=False,
44 | ),
45 | "created_time": created_time.isoformat(),
46 | "edited_time": edited_time.isoformat(),
47 | "pinned": pinned,
48 | "deleted": deleted,
49 | }
50 |
51 | notes.append(note)
52 | except Exception as e:
53 | print(f"Error while reading the input file: {e}")
54 | exit(-1)
55 |
56 | return notes, []
57 |
--------------------------------------------------------------------------------
/docs/external_imports/inputs/d_notes.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/external_imports/inputs/d_notes.zip
--------------------------------------------------------------------------------
/docs/external_imports/inputs/samsung_notes.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/external_imports/inputs/samsung_notes.zip
--------------------------------------------------------------------------------
/docs/external_imports/outputs/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/external_imports/outputs/.gitkeep
--------------------------------------------------------------------------------
/docs/external_imports/requirements.txt:
--------------------------------------------------------------------------------
1 | python-dateutil
--------------------------------------------------------------------------------
/docs/github/social_preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/github/social_preview.png
--------------------------------------------------------------------------------
/docs/github/social_preview.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/github/social_preview.psd
--------------------------------------------------------------------------------
/docs/google_play/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/google_play/banner.png
--------------------------------------------------------------------------------
/docs/google_play/banner.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/google_play/banner.psd
--------------------------------------------------------------------------------
/docs/google_play/changelogs_max_length.txt:
--------------------------------------------------------------------------------
1 | 500 chars
--------------------------------------------------------------------------------
/docs/google_play/icon_google_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/docs/google_play/icon_google_play.png
--------------------------------------------------------------------------------
/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | json_key_file("fastlane/localmaterialnotes_fastlane-supply_key.json")
2 | package_name("com.maelchiotti.localmaterialnotes")
3 |
--------------------------------------------------------------------------------
/fastlane/Fastfile:
--------------------------------------------------------------------------------
1 | default_platform(:android)
2 |
3 | platform :android do
4 | desc "Build AAB"
5 | lane :build_aab do
6 | sh("flutter build appbundle --release")
7 | end
8 |
9 | # bundle exec fastlane deploy_production
10 | desc "Deploy - Production"
11 | lane :deploy_production do
12 | build_aab
13 |
14 | supply(
15 | track: 'production',
16 | package_name: 'com.maelchiotti.localmaterialnotes',
17 | aab: 'build/app/outputs/bundle/release/app-release.aab',
18 | skip_upload_apk: true
19 | )
20 | end
21 |
22 | # bundle exec fastlane deploy_internal
23 | desc "Deploy - Internal"
24 | lane :deploy_internal do
25 | build_aab
26 |
27 | supply(
28 | track: 'internal',
29 | package_name: 'com.maelchiotti.localmaterialnotes',
30 | aab: 'build/app/outputs/bundle/release/app-release.aab',
31 | skip_upload_apk: true
32 | )
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/cs-CZ/full_description.txt:
--------------------------------------------------------------------------------
1 |
Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/cs-CZ/short_description.txt:
--------------------------------------------------------------------------------
1 | Jednoduché, lokální poznámky s material designem
--------------------------------------------------------------------------------
/fastlane/metadata/android/cs-CZ/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/short_description.txt:
--------------------------------------------------------------------------------
1 | Einfache, lokale Notizen-App im Material-Design
--------------------------------------------------------------------------------
/fastlane/metadata/android/de-DE/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/100.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Auto JSON backup
3 | - JSON backup encryption
4 | - Customize swipe actions
5 | - Hide app from recent apps and prevent screenshots
6 | - Show checklist button in the toolbar
7 | - Enable high refresh rate
8 | - Russian translation
9 |
10 | CHANGED
11 | - New settings page layout
12 |
13 | FIXED
14 | - Notes tiles issues
15 | - Keyboard opening when toggling a checkbox
16 | - Keyboard popping back up after using the back gesture
17 | - Exit selection mode on back action
18 |
19 | REMOVED
20 | - Swipe actions in the bin
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/110.txt:
--------------------------------------------------------------------------------
1 | FIXED
2 | - Exiting the editor with the device back button or the back gesture (not the app back button) causes the content of the note to be displayed in any other note opened afterwards
3 | - Special characters incorrectly decoded when importing a JSON file
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/120.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Portuguese translation
3 |
4 | FIXED
5 | - Auto export settings tile not updating after disabling auto export
6 | - Notes sorted by their created time instead of their edited time
7 | - Focus on the note content not requested when the title is validated
8 | - Typos
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/130.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Release on F-Droid
3 | - Choose the auto backup directory
4 | - Choose to only show the titles of the notes (can be disabled in the search view)
5 | - Choose to focus title instead of content when creating new note
6 | - Choose to disable subdued color of notes content preview
7 | - Choose to change the text scaling
8 | - Chinese simplified translation
9 |
10 | FIXED
11 | - Search view not black in black theme mode
12 | - Failure to set refresh rate below Android 6
13 | - Failure to get the write permission when writing export files
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/140.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Toolbar button to add a link to the selected text
3 | - Button to toggle the editor between editing mode and reading mode
4 | - Setting to open the editor in reading mode by default
5 | - Copy to clipboard menu and swipe action
6 | - Share swipe action
7 | - Live preview when selecting the text scaling
8 |
9 | CHANGED
10 | - Settings values display
11 |
12 | FIXED
13 | - Text scaling popup having a wrong title
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/150.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Error page shown when a page fails to load, with the ability to copy and export the error logs
3 |
4 | IMPROVED
5 | - Reliability of the automatic exports
6 |
7 | FIXED
8 | - Value of the setting on the settings tiles not using a subdued color when disabled
9 | - Too small note pinned icon on the notes tiles
10 | - Too small application icon
11 |
12 | REMOVED
13 | - READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions that were added by mistake
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/160.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Script to convert Samsung Notes exports (see the GitHub repository)
3 | - Ability to copy the logs and to export them to a file
4 |
5 | CHANGED
6 | - Improve the style of the settings tiles
7 |
8 | FIXED
9 | - Using the system back button or back gesture closes the app
10 | - Auto export directory picker fails when choosing a directory
11 | - JSON export file using the .txt extension instead of .json
12 | - Buttons in the editor app bar not disabled in reading mode
13 | - Button to toggle editor mode not hidden for deleted notes
14 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/170.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Ability to categorize the notes with labels
3 | - Allow to sort the notes by their creation date
4 | - Allow to use a white text in dark theme
5 | - Polish translation
6 |
7 | CHANGED
8 | - Improve logs
9 | - Move accessibility settings to their own page
10 |
11 | FIXED
12 | - Failure to add a note via the share action of the quick action
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/180.txt:
--------------------------------------------------------------------------------
1 | FIXED
2 | - Crash at startup because of the sorting method setting
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/190.txt:
--------------------------------------------------------------------------------
1 | FIXED
2 | - Error at startup because of the ascending sorting setting
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/200.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Backup labels
3 | - Backup settings
4 | - Convert DNotes exports (see GitHub)
5 | - Hindi translation
6 |
7 | CHANGED
8 | - Moved button to change editor mode to app bar
9 |
10 | FIXED
11 | - Labels count shown in about dialog when disabled
12 | - Wrong color in label color picker when editing
13 | - Going back after selecting labels closes app
14 | - Missing message if no labels exist on selection
15 | - Confirmation when deleting labels
16 | - Missing explanation on what disabling labels does
17 | - Wrong sort order reset
18 | - Wrong texts on buttons
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/210.txt:
--------------------------------------------------------------------------------
1 | FIXED
2 | - Crash when loading the theming preference
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/220.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Drastically better search performance with typo tolerance
3 | - Setting to make titles of notes bigger
4 | - Czech translation
5 |
6 | CHANGED
7 | - Layout / swipe action not updating correctly
8 | - Going back from a label page or the Manage labels page goes back to the notes list
9 | - Organization of settings
10 |
11 | FIXED
12 | - Last edited date of a note being changed when the note is pinned or unpinned
13 | - Black screen when deleting or restoring a note from the editor
14 | - Malformed URL when opening a link from the editor
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/230.txt:
--------------------------------------------------------------------------------
1 | FIXED
2 | - Bin page not displaying the deleted notes
3 | - Missing translation for "No labels" placeholder
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/240.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Choose the font of the application and the notes editor
3 | - More actions on multi-selection: share and add labels
4 | - Swipe actions in the bin
5 |
6 | FIXED
7 | - Already existing notes missing while searching
8 | - Back action from the labels pages
9 | - Wrong icon for hidden labels
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/250.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Setting to choose the maximum number of content preview lines to show in the notes tiles
3 | - Italian translation
4 |
5 | FIXED
6 | - Main notes page not displaying all the notes after going back from a labels page
7 | - Crash when using an horizontal line in the the first line of the editor
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/260.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Chinese Traditional translation
3 |
4 | CHANGED
5 | - Enable automatic export by default
6 | - Background of the notes tiles is slightly darker (like the tiles in the search view)
7 | - Print logs to the console in release mode
8 |
9 | FIXED
10 | - Custom font not applied to lists in the editor
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/280.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - New notes types: plain text, markdown, checklist
3 | - Archive notes
4 | - Cancel actions
5 | - Lock the application, a note or a all notes with a label
6 | - Highlight searched text
7 | - Setting to improve titles visibility
8 | - Automatic bin emptying
9 | - Donation links
10 |
11 | CHANGED
12 | - 3 rich text editor toolbar appearance options
13 | - Organize notes in folders in markdown exports
14 | - Animated labels filters
15 | - Replaced "label" with "tag"
16 |
17 | FIXED
18 | - Auto delete empty notes
19 | - Back button not working as expected
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/70.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Release to IzzyOnDroid
3 | - Grid view
4 | - Advanced text formatting
5 | - Undo/redo while editing
6 | - Setting to toggle advanced text formatting, undo/redo and checklists
7 |
8 | REMOVED
9 | - "Untitled note" label
10 |
11 | CHANGED
12 | - Improve the search precision
13 | - Improve markdown export
14 | - Going back from the settings goes back to the previous page
15 |
16 | FIXED
17 | - Hide note preview if empty
18 | - Notes not sorted after being updated
19 | - Support RTL for paddings
20 | - Many small issues
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/changelogs/90.txt:
--------------------------------------------------------------------------------
1 | ADDED
2 | - Spanish translation
3 | - Toggleable background for notes tiles
4 |
5 | CHANGED
6 | - Improved speed of editing/deleting multiple notes
7 | - Use less vibrant color for editor toolbar
8 |
9 | FIXED
10 | - Going back from licences list doesn't close page
11 | - Going back from editor page while menu is open goes back to notes list
12 | - Empty note still shown until notes list refreshed
13 | - Devices with RTL language not having app use RTL layout
14 | - Wrong icon size on splash screen
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/featureGraphic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/fastlane/metadata/android/en-US/images/featureGraphic.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/fastlane/metadata/android/en-US/images/icon.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/5_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/fastlane/metadata/android/en-US/images/phoneScreenshots/5_en-US.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/6_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/fastlane/metadata/android/en-US/images/phoneScreenshots/6_en-US.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/7_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/fastlane/metadata/android/en-US/images/phoneScreenshots/7_en-US.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/8_en-US.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelchiotti/LocalMaterialNotes/cdb3236bb4e9353aab6037a413766ed1791afe87/fastlane/metadata/android/en-US/images/phoneScreenshots/8_en-US.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/short_description.txt:
--------------------------------------------------------------------------------
1 | Simple, local, material design notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/es-ES/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/es-ES/short_description.txt:
--------------------------------------------------------------------------------
1 | Notas simples, locales, en Material Design
--------------------------------------------------------------------------------
/fastlane/metadata/android/es-ES/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/100.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Sauvegarde auto en JSON
3 | - Chiffrage de la sauvegarde JSON
4 | - Personnaliser les balayages
5 | - Masquer dans applications récentes et empêcher captures
6 | - Afficher bouton cases à cocher dans barre d'outils
7 | - Activer taux de rafraîchissement élevé
8 | - Traduction en russe
9 |
10 | MODIFIÉ
11 | - Nouvelle disposition des paramètres
12 |
13 | CORRIGÉ
14 | - Problèmes des tuiles
15 | - Ouverture du clavier involontaires (cases à cocher, retour)
16 | - Quitter mode sélection après retour
17 |
18 | SUPPRIMÉ
19 | - Actions de balayage dans la corbeille
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/110.txt:
--------------------------------------------------------------------------------
1 | CORRIGÉ
2 | - Quitter l'éditeur à l'aide du bouton retour de l'appareil ou du geste retour (et non du bouton retour de l'application) entraîne l'affichage du contenu de la note dans toute autre note ouverte par la suite
3 | - Caractères spéciaux mal décodés lors de l'importation d'un fichier JSON
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/120.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Localisation en portugais
3 |
4 | CORRIGÉ
5 | - La tuile des paramètres d'export automatique ne se mettait pas à jour après avoir désactivé l'export automatique
6 | - Notes triées en fonction de leur date de création au lieu de leur date d'édition
7 | - Le focus sur le contenu de la note n'est pas demandée lorsque le titre est validé
8 | - Fautes d'orthographe
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/130.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Publication sur F-Droid
3 | - Choisir répertoire sauvegarde automatique
4 | - Choisir afficher que titres des notes (peut être désactivé dans la recherche)
5 | - Choisir de focus le titre au lieu du contenu lors d'une nouvelle note
6 | - Désactiver couleur atténuée de l'aperçu du contenu des notes
7 | - Modifier l'échelle du texte
8 | - Traduction en chinois simplifié
9 |
10 | CORRIGÉ
11 | - Recherche pas noire en thème noir
12 | - Échec réglage fréquence de rafraîchissement sous Android 6
13 | - Échec lors de l'écriture des exports
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/140.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Bouton dans la barre d'outils pour ajouter un lien au texte sélectionné
3 | - Bouton pour basculer l'éditeur entre le mode édition et le mode lecture
4 | - Réglage pour ouvrir l'éditeur en mode lecture par défaut
5 | - Menu et action de balayage pour copier dans le presse-papier
6 | - Action de balayage pour partager
7 | - Aperçu en direct lors de la sélection de la mise à l'échelle du texte
8 |
9 | MODIFIÉ
10 | - Affichage des valeurs des paramètres
11 |
12 | CORRIGÉ
13 | - Titre de la popup de mise à l'échelle du texte erroné
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/150.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Page d'erreur affichée lorsqu'une page ne se charge pas, avec la possibilité de copier et d'exporter les logs d'erreur
3 |
4 | AMÉLIORÉ
5 | - Fiabilité des exports automatiques
6 |
7 | CORRIGÉ
8 | - La valeur du paramètre sur les tuiles de paramètres n'utilise pas une couleur atténuée lorsqu'elle est désactivée
9 | - Trop petite icône de note épinglée sur les tuiles de notes
10 | - Trop petite icône d'application
11 |
12 | SUPPRIMÉ
13 | - Permissions READ_EXTERNAL_STORAGE et WRITE_EXTERNAL_STORAGE ajoutées par erreur
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/160.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Script pour convertir exports de Samsung Notes (voir dépôt GitHub)
3 | - Possibilité de copier les logs et les exporter vers un fichier
4 |
5 | MODIFIÉ
6 | - Amélioration du style des tuiles de paramètres
7 |
8 | CORRIGÉ
9 | - Bouton ou geste retour du système ferme l'application
10 | - Sélecteur du répertoire d'export automatique échoue
11 | - Fichier d'export JSON avec extension .txt
12 | - Boutons de la barre de l'éditeur pas désactivés en mode lecture
13 | - Bouton du mode de l'éditeur pas masqué pour les notes supprimées
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/170.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Possibilité de catégoriser les notes avec des étiquettes
3 | - Possibilité de trier les notes en fonction de leur date de création
4 | - Possibilité d'utiliser un texte blanc avec le thème sombre
5 | - Traduction en polonais
6 |
7 | MODIFIÉ
8 | - Amélioration des logs
9 | - Déplacement des paramètres d'accessibilité vers leur propre page
10 |
11 | CORRIGÉ
12 | - Échec de l'ajout d'une note via l'action de partage ou l'action rapide de l'écran d'accueil
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/180.txt:
--------------------------------------------------------------------------------
1 | CORRIGÉ
2 | - Crash au démarrage à cause du paramètre de méthode de tri
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/190.txt:
--------------------------------------------------------------------------------
1 | CORRIGÉ
2 | - Erreur au démarrage à cause du paramètre de tri ascendant
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/200.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Export des étiquettes
3 | - Export des paramètres
4 | - Conversion exports DNotes (voir GitHub)
5 | - Hindi
6 |
7 | MODIFIÉ
8 | - Déplacement bouton changement mode
9 |
10 | CORRIGÉ
11 | - Nombre étiquettes affiché si désactivées
12 | - Mauvaise couleur sélecteur couleurs
13 | - Retour après sélection d'étiquettes ferme
14 | - Message manquant si aucune étiquettes
15 | - Confirmation lors de la suppression d'étiquettes
16 | - Manque d'explication sur désactivation des étiquettes
17 | - Réinitialisation erronée ordre de tri
18 | - Textes erronés de boutons
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/210.txt:
--------------------------------------------------------------------------------
1 | CORRIGÉ
2 | - Crash lors du chargement de la préférence du thème
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/220.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Amélioration des performances de recherche avec tolérance des fautes de frappe
3 | - Réglage pour agrandir titres des notes
4 | - Traduction tchèque
5 |
6 | MODIFIÉ
7 | - Mise en page / balayage ne se mettent pas à jour correctement
8 | - Retour depuis les étiquettes ramène à la liste des notes
9 | - Organisation des paramètres
10 |
11 | CORRIGÉ
12 | - Date de dernière modification d'une note est modifiée lorsque la note est épinglée ou désépinglée
13 | - Écran noir après suppression/restauration de note
14 | - URL malformée des liens
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/230.txt:
--------------------------------------------------------------------------------
1 | CORRIGÉ
2 | - Corbeille n'affiche pas les notes supprimées
3 | - Traduction manquante pour le texte "Pas d'étiquette"
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/240.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Choix de la police de l'application et de l'éditeur de notes
3 | - Plus d'actions en multi-sélection : partager et ajouter des étiquettes
4 | - Actions de balayage dans la corbeille
5 |
6 | CORRIGÉ
7 | - Absence des notes déjà existantes lors de la recherche
8 | - Action de retour depuis les pages d'étiquettes
9 | - Mauvaise icône pour les étiquettes cachées
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/250.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Paramètre permettant de choisir le nombre maximum de lignes de l'aperçu du contenu à afficher dans les tuiles de notes
3 | - Traduction en italien
4 |
5 | CORRIGÉ
6 | - La page principale des notes n'affiche pas toutes les notes après un retour depuis une page d'étiquettes
7 | - Crash lors de l'utilisation d'une ligne horizontale dans la première ligne de l'éditeur
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/260.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Traduction en chinois traditionnel
3 |
4 | MODIFIÉ
5 | - Activation des exports automatiques par défault
6 | - L'arrière-plan des tuiles de notes est légèrement plus foncé (comme les tuiles de la vue de recherche)
7 | - Logs affichés dans la console en production
8 |
9 | CORRIGÉ
10 | - Police personnalisée non appliquée dans l'éditeur
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/280.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Types de notes : texte brut, markdown, liste de contrôle
3 | - Archivage des notes
4 | - Annuler des actions
5 | - Verrouillage de l'app, d'une note ou d'une étiquette
6 | - Mise en évidence du texte recherché
7 | - Paramètre pour améliorer la visibilité des titres
8 | - Vidage automatique corbeille
9 | - Liens donation
10 |
11 | MODIFIÉ
12 | - 3 apparences de la barre d'outils
13 | - Organiser les notes dans des dossiers dans les exports Markdown
14 | - Animation filtres étiquettes
15 |
16 | CORRIGÉ
17 | - Suppression auto notes vides
18 | - Bouton retour
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/70.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Publication sur IzzyOnDroid
3 | - Vue en grille
4 | - Formatage avancé
5 | - Annuler/refaire pendant l'édition
6 | - Paramètre pour basculer formatage avancé, annuler/rétablir et checklists
7 |
8 | SUPPRIMÉ
9 | - Titre "Note sans titre"
10 |
11 | MODIFIÉ
12 | - Amélioration de la recherche
13 | - Amélioration de l'export markdown
14 | - Retour depuis les paramètres renvoie à la page précédente
15 |
16 | CORRIGÉ
17 | - Cacher aperçu de la note si vide
18 | - Notes non triées après une mises à jour
19 | - Support du RTL des espacements
20 | - Problèmes divers
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/changelogs/90.txt:
--------------------------------------------------------------------------------
1 | AJOUTÉ
2 | - Traduction en espagnol
3 | - Fond désactivable pour les tuiles des notes
4 |
5 | CHANGÉ
6 | - Vitesse d'édition/modification améliorées
7 | - Couleur moins vibrante pour la barre d'outils
8 |
9 | CORRIGÉ
10 | - Retour depuis liste des licences ne ferme pas la page
11 | - Retour depuis l'éditeur avec menu est retourne sur la liste des notes
12 | - Notes vides toujours affichées
13 | - Appareils avec langue RTL n'utilisent pas la disposition RTL
14 | - Taille de l'icône légèrement erronée sur le splash screen
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes est une application de prise de notes textuelles, qui vise la simplicité. Elle adopte le style Material Design. Elle stocke les notes localement et n'a aucune permission internet, vous êtes donc le seul à pouvoir accéder aux notes.
Prenez des notes
Rédigez des notes textuelles (titre et contenu) Choisissez entre des notes en texte brut, markdown, texte riche ou des listes de contrôle Utilisez l'action rapide de votre écran d'accueil pour ajouter rapidement une note. Organisez
Recherchez dans vos notes Triez vos notes par date ou par titre, par ordre croissant ou décroissant Affichez vos notes sous forme de liste ou de grille Épinglez et archivez vos notes Récupérez vos notes supprimées de la corbeille Catégoriez
Catégoriez vos notes avec des étiquettes Distinguez vos étiquettes avec leur couleur Épinglez et masquez vos étiquettes Partagez & sauvegardez
Partagez du texte à partir d'autres applications pour l'ajouter directement à une note Partagez vos notes sous forme de texte Exportez vos notes au format JSON, manuellement ou automatiquement, et importez-les à nouveau Exportez vos notes au format Markdown Protégez
Ne vous inquiétez pas de la façon dont vos données sont traitées : elles ne peuvent pas quitter votre appareil car l'application n'a pas d'autorisations Internet Verrouillez l'application, une note en particulier, ou toutes les notes avec une étiquette en particulier Chiffrez vos exports Personnalisez
Choisissez votre langue Choisissez votre thème (clair, foncé ou noir) Choisissez si vous voulez que votre thème soit dynamique (utilise les couleurs de votre arrière-plan) Choisissez quels types de notes vous voulez activer
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/short_description.txt:
--------------------------------------------------------------------------------
1 | Notes simples, locales, en material design
--------------------------------------------------------------------------------
/fastlane/metadata/android/fr-FR/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/hi-IN/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/hi-IN/short_description.txt:
--------------------------------------------------------------------------------
1 | सरल, स्थानीय, मैटेरियल डिज़ाइन नोट्स
--------------------------------------------------------------------------------
/fastlane/metadata/android/hi-IN/title.txt:
--------------------------------------------------------------------------------
1 | मैटेरियल नोट्स
--------------------------------------------------------------------------------
/fastlane/metadata/android/id/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/id/short_description.txt:
--------------------------------------------------------------------------------
1 | Simple, local, material design notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/id/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/it-IT/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/it-IT/short_description.txt:
--------------------------------------------------------------------------------
1 | Note semplici, locali e in material design
--------------------------------------------------------------------------------
/fastlane/metadata/android/it-IT/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/pl-PL/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/pl-PL/short_description.txt:
--------------------------------------------------------------------------------
1 | Proste, lokalne notatki w stylu Material Design
--------------------------------------------------------------------------------
/fastlane/metadata/android/pl-PL/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/pt-PT/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/pt-PT/short_description.txt:
--------------------------------------------------------------------------------
1 | Simple, local, material design notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/pt-PT/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/ru-RU/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/ru-RU/short_description.txt:
--------------------------------------------------------------------------------
1 | Простые, локальные заметки в стиле Material Design
--------------------------------------------------------------------------------
/fastlane/metadata/android/ru-RU/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/tr-TR/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/tr-TR/short_description.txt:
--------------------------------------------------------------------------------
1 | Basit, çevrimdışı, materyal tasarımlı notlar
--------------------------------------------------------------------------------
/fastlane/metadata/android/tr-TR/title.txt:
--------------------------------------------------------------------------------
1 | Material Not
--------------------------------------------------------------------------------
/fastlane/metadata/android/zh-CN/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/zh-CN/short_description.txt:
--------------------------------------------------------------------------------
1 | 简单、本地、Material 设计笔记
--------------------------------------------------------------------------------
/fastlane/metadata/android/zh-CN/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/fastlane/metadata/android/zh-TW/full_description.txt:
--------------------------------------------------------------------------------
1 | Material Notes is a text-based note-taking application, aimed at simplicity. It embraces Material Design. It stores the notes locally and doesn't have any internet permissions, so you are the only one that can access the notes.
Take notes
Write text notes (title and content) Choose between plain text, markdown, rich text or checklist notes Use the quick action from your home screen to quickly add a note Organize
Search though your notes Sort your notes by date or title, in ascending or descending order Display your notes in a list or a grid view Pin and archive your notes Recover your deleted notes from the bin Categorize
Categorize your notes with tags Distinguish your tags with their color Pin and hide your tags Share & backup
Share text from other applications to add it directly to a note Share your notes as text Export your notes as JSON, manually or automatically, and import them back Export your notes as Markdown Protect
Never worry about how your data is handled: it cannot leave your device as the application doesn't have any internet permissions Lock the application, a specific notes, or all notes with a specific tag Encrypt your JSON exports Customize
Choose your language Choose your theme (light, dark or black) Choose if you want your theme to be dynamic (use colors from your background) Choose which notes types you want enabled
--------------------------------------------------------------------------------
/fastlane/metadata/android/zh-TW/short_description.txt:
--------------------------------------------------------------------------------
1 | 簡單易用、本機操作、Material 設計之筆記
--------------------------------------------------------------------------------
/fastlane/metadata/android/zh-TW/title.txt:
--------------------------------------------------------------------------------
1 | Material Notes
--------------------------------------------------------------------------------
/flutter_launcher_icons.yaml:
--------------------------------------------------------------------------------
1 | flutter_launcher_icons:
2 | android: true
3 | min_sdk_android: 21
4 | image_path_android: "assets/icons/icon.png"
5 | adaptive_icon_foreground: "assets/icons/icon_foreground.png"
6 | adaptive_icon_monochrome: "assets/icons/icon_foreground_monochrome.png"
7 | adaptive_icon_foreground_inset: 0
8 | adaptive_icon_background: "#2278e9"
--------------------------------------------------------------------------------
/flutter_native_splash.yaml:
--------------------------------------------------------------------------------
1 | flutter_native_splash:
2 | image: "assets/icons/icon.png"
3 | color: "#ffffff"
4 | icon_background_color: "#ffffff"
5 |
6 | image_dark: "assets/icons/icon.png"
7 | color_dark: "#000000"
8 | icon_background_color_dark: "#000000"
9 |
10 | android_12:
11 | image: "assets/icons/icon_android_12.png"
12 | color: "#ffffff"
13 |
14 | image_dark: "assets/icons/icon_android_12.png"
15 | color_dark: "#000000"
16 | icon_background_color_dark: "#000000"
17 |
18 | ios: false
19 | web: false
--------------------------------------------------------------------------------
/l10n.yaml:
--------------------------------------------------------------------------------
1 | format: true
2 | use-escaping: true
3 | nullable-getter: false
4 | synthetic-package: false
5 | required-resource-attributes: true
6 |
7 | arb-dir: lib/l10n/translations
8 | template-arb-file: app_en.arb
9 |
10 | output-dir: lib/l10n/app_localizations
11 | output-localization-file: app_localizations.g.dart
12 |
13 | untranslated-messages-file: lib/l10n/untranslated.txt
--------------------------------------------------------------------------------
/lib/common/actions/labels/add.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 |
4 | import '../../../models/label/label.dart';
5 | import '../../../pages/labels/dialogs/label_dialog.dart';
6 | import '../../../providers/labels/labels/labels_provider.dart';
7 | import '../../extensions/build_context_extension.dart';
8 |
9 | /// Adds a label.
10 | Future addLabel(BuildContext context, WidgetRef ref) async {
11 | final label = await showAdaptiveDialog(
12 | context: context,
13 | useRootNavigator: false,
14 | builder: (context) => LabelDialog(title: context.l.dialog_label_add),
15 | );
16 |
17 | if (label == null) {
18 | return;
19 | }
20 |
21 | await ref.read(labelsProvider.notifier).edit(label);
22 | }
23 |
--------------------------------------------------------------------------------
/lib/common/actions/labels/delete.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 |
4 | import '../../../models/label/label.dart';
5 | import '../../../providers/labels/labels/labels_provider.dart';
6 | import '../../dialogs/confirmation_dialog.dart';
7 | import '../../extensions/build_context_extension.dart';
8 | import 'select.dart';
9 |
10 | /// Deletes the [label].
11 | ///
12 | /// Returns `true` if the [label] was deleted, `false` otherwise.
13 | ///
14 | /// First, asks for a confirmation if needed.
15 | Future deleteLabel(BuildContext context, WidgetRef ref, {required Label label}) async {
16 | if (!await askForConfirmation(
17 | context,
18 | context.l.dialog_delete_label,
19 | context.l.dialog_delete_label_body(1),
20 | context.l.dialog_delete_label,
21 | irreversible: true,
22 | )) {
23 | return false;
24 | }
25 |
26 | return await ref.read(labelsProvider.notifier).delete([label]);
27 | }
28 |
29 | /// Deletes the [labels].
30 | ///
31 | /// Returns `true` if the [labels] were deleted, `false` otherwise.
32 | ///
33 | /// First, asks for a confirmation if needed.
34 | Future deleteLabels(BuildContext context, WidgetRef ref, {required List labels}) async {
35 | if (!await askForConfirmation(
36 | context,
37 | context.l.dialog_delete_label,
38 | context.l.dialog_delete_label_body(labels.length),
39 | context.l.dialog_delete_label,
40 | irreversible: true,
41 | )) {
42 | return false;
43 | }
44 |
45 | final succeeded = await ref.read(labelsProvider.notifier).delete(labels);
46 |
47 | if (context.mounted) {
48 | exitLabelsSelectionMode(ref);
49 | }
50 |
51 | return succeeded;
52 | }
53 |
--------------------------------------------------------------------------------
/lib/common/actions/labels/edit.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 |
4 | import '../../../models/label/label.dart';
5 | import '../../../pages/labels/dialogs/label_dialog.dart';
6 | import '../../../providers/labels/labels/labels_provider.dart';
7 | import '../../extensions/build_context_extension.dart';
8 |
9 | /// Opens the dialog to edit the [label].
10 | Future editLabel(BuildContext context, WidgetRef ref, {required Label label}) async {
11 | final editedLabel = await showAdaptiveDialog(
12 | context: context,
13 | useRootNavigator: false,
14 | builder: (context) => LabelDialog(title: context.l.dialog_label_edit, label: label),
15 | );
16 |
17 | if (editedLabel == null) {
18 | return;
19 | }
20 |
21 | await ref.read(labelsProvider.notifier).edit(editedLabel);
22 | }
23 |
--------------------------------------------------------------------------------
/lib/common/actions/labels/lock.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:local_auth/local_auth.dart';
4 |
5 | import '../../../models/label/label.dart';
6 | import '../../../providers/labels/labels/labels_provider.dart';
7 | import '../../extensions/build_context_extension.dart';
8 | import '../../preferences/preference_key.dart';
9 | import 'select.dart';
10 |
11 | /// Toggles whether the [labels] are locked.
12 | Future toggleLockLabels(BuildContext context, WidgetRef ref, {required List labels}) async {
13 | final lockLabelPreference = PreferenceKey.lockLabel.preferenceOrDefault;
14 | final anyLocked = labels.any((label) => label.locked);
15 |
16 | // If the lock label setting is enabled and a label was locked, then ask to authenticate
17 | if (lockLabelPreference && anyLocked) {
18 | final bool authenticated = await LocalAuthentication().authenticate(
19 | localizedReason: context.l.lock_page_reason_action,
20 | );
21 |
22 | if (!authenticated) {
23 | return false;
24 | }
25 | }
26 |
27 | final toggled = await ref.read(labelsProvider.notifier).toggleLock(labels);
28 |
29 | exitLabelsSelectionMode(ref);
30 |
31 | return toggled;
32 | }
33 |
--------------------------------------------------------------------------------
/lib/common/actions/labels/pin.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_riverpod/flutter_riverpod.dart';
2 |
3 | import '../../../models/label/label.dart';
4 | import '../../../providers/labels/labels/labels_provider.dart';
5 | import 'select.dart';
6 |
7 | /// Toggles whether the [labels] are pinned.
8 | Future togglePinLabels(WidgetRef ref, {required List labels}) async {
9 | await ref.read(labelsProvider.notifier).togglePin(labels);
10 |
11 | exitLabelsSelectionMode(ref);
12 | }
13 |
--------------------------------------------------------------------------------
/lib/common/actions/labels/select.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_riverpod/flutter_riverpod.dart';
2 |
3 | import '../../../models/label/label.dart';
4 | import '../../../providers/labels/labels/labels_provider.dart';
5 | import '../../../providers/notifiers/notifiers.dart';
6 |
7 | /// Toggles the select status of the [label].
8 | void toggleSelectLabel(WidgetRef ref, {required Label label}) {
9 | label.selected ? ref.read(labelsProvider.notifier).unselect(label) : ref.read(labelsProvider.notifier).select(label);
10 | }
11 |
12 | /// Selects all the labels.
13 | void selectAllLabels(WidgetRef ref) {
14 | ref.read(labelsProvider.notifier).selectAll();
15 | }
16 |
17 | /// Unselects all the labels.
18 | void unselectAllLabels(WidgetRef ref) {
19 | ref.read(labelsProvider.notifier).unselectAll();
20 | }
21 |
22 | /// Exits the labels selection mode.
23 | ///
24 | /// First unselects all the labels.
25 | void exitLabelsSelectionMode(WidgetRef ref) {
26 | unselectAllLabels(ref);
27 |
28 | isLabelsSelectionModeNotifier.value = false;
29 | }
30 |
--------------------------------------------------------------------------------
/lib/common/actions/labels/visible.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_riverpod/flutter_riverpod.dart';
2 |
3 | import '../../../models/label/label.dart';
4 | import '../../../providers/labels/labels/labels_provider.dart';
5 | import 'select.dart';
6 |
7 | /// Toggles whether the [labels] are visible.
8 | Future toggleVisibleLabels(WidgetRef ref, {required List labels}) async {
9 | await ref.read(labelsProvider.notifier).toggleVisible(labels);
10 |
11 | exitLabelsSelectionMode(ref);
12 | }
13 |
--------------------------------------------------------------------------------
/lib/common/actions/notes/about.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../../pages/editor/sheets/about_sheet.dart';
4 | import '../../constants/constants.dart';
5 |
6 | /// Show the about drawer for the current note.
7 | Future showAboutNote() async {
8 | await showModalBottomSheet(
9 | context: rootNavigatorKey.currentContext!,
10 | clipBehavior: Clip.hardEdge,
11 | showDragHandle: true,
12 | isScrollControlled: true,
13 | useSafeArea: true,
14 | builder: (context) => const AboutSheet(),
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/lib/common/actions/notes/copy.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 |
4 | import '../../../models/note/note.dart';
5 | import '../../extensions/build_context_extension.dart';
6 | import '../../ui/snack_bar_utils.dart';
7 |
8 | /// Copies the content of the [note] to the clipboard.
9 | Future copyNote(BuildContext context, {required Note note}) async {
10 | await Clipboard.setData(ClipboardData(text: note.contentPreview));
11 |
12 | if (!context.mounted) {
13 | return;
14 | }
15 |
16 | if (context.mounted) {
17 | SnackBarUtils().show(context, text: context.l.snack_bar_copied(1));
18 | }
19 | }
20 |
21 | /// Copies the content of the [notes] to the clipboard.
22 | Future copyNotes(BuildContext context, {required List notes}) async {
23 | final text = notes.map((note) => note.contentPreview).join('\n\n\n').trim();
24 |
25 | await Clipboard.setData(ClipboardData(text: text));
26 |
27 | if (context.mounted) {
28 | SnackBarUtils().show(context, text: context.l.snack_bar_copied(notes.length));
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/common/actions/notes/lock.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:local_auth/local_auth.dart';
4 |
5 | import '../../../models/note/note.dart';
6 | import '../../../models/note/note_status.dart';
7 | import '../../../providers/notes/notes_provider.dart';
8 | import '../../../providers/notifiers/notifiers.dart';
9 | import '../../extensions/build_context_extension.dart';
10 | import '../../preferences/preference_key.dart';
11 | import 'select.dart';
12 |
13 | /// Toggles whether the [notes] are locked.
14 | Future toggleLockNotes(
15 | BuildContext context,
16 | WidgetRef ref, {
17 | required List notes,
18 | bool requireAuthentication = false,
19 | }) async {
20 | if (requireAuthentication) {
21 | final lockNotePreference = PreferenceKey.lockNote.preferenceOrDefault;
22 | final anyLocked = notes.any((note) => note.locked);
23 |
24 | // If the lock note setting is enabled and a note was locked, then ask to authenticate
25 | if (lockNotePreference && anyLocked) {
26 | final bool authenticated = await LocalAuthentication().authenticate(
27 | localizedReason: context.l.lock_page_reason_action,
28 | );
29 |
30 | if (!authenticated) {
31 | return false;
32 | }
33 | }
34 | }
35 |
36 | final toggled = await ref
37 | .read(notesProvider(status: NoteStatus.available, label: currentLabelFilter).notifier)
38 | .toggleLock(notes);
39 |
40 | if (context.mounted && notes.length > 1) {
41 | exitNotesSelectionMode(context, ref, notesStatus: NoteStatus.available);
42 | }
43 |
44 | return toggled;
45 | }
46 |
--------------------------------------------------------------------------------
/lib/common/actions/notes/pin.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 |
4 | import '../../../models/note/note.dart';
5 | import '../../../models/note/note_status.dart';
6 | import '../../../providers/notes/notes_provider.dart';
7 | import '../../../providers/notifiers/notifiers.dart';
8 | import 'select.dart';
9 |
10 | /// Toggles whether the [notes] are pinned.
11 | Future togglePinNotes(BuildContext context, WidgetRef ref, {required List notes}) async {
12 | final toggled = await ref
13 | .read(notesProvider(status: NoteStatus.available, label: currentLabelFilter).notifier)
14 | .togglePin(notes);
15 |
16 | if (context.mounted && notes.length > 1) {
17 | exitNotesSelectionMode(context, ref, notesStatus: NoteStatus.available);
18 | }
19 |
20 | return toggled;
21 | }
22 |
--------------------------------------------------------------------------------
/lib/common/actions/notes/pop.dart:
--------------------------------------------------------------------------------
1 | import '../../constants/constants.dart';
2 |
3 | /// Closes the expandable FAB to add a note if it is open.
4 | void closeAddNoteFabIfOpen() {
5 | if (addNoteFabKey.currentState != null && addNoteFabKey.currentState!.isOpen) {
6 | addNoteFabKey.currentState!.toggle();
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/lib/common/actions/notes/select.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 |
4 | import '../../../models/note/note.dart';
5 | import '../../../models/note/note_status.dart';
6 | import '../../../providers/notes/notes_provider.dart';
7 | import '../../../providers/notifiers/notifiers.dart';
8 |
9 | /// Toggles the select status of the [note].
10 | void toggleSelectNote(WidgetRef ref, {required Note note}) {
11 | ref.read(notesProvider(status: note.status, label: currentLabelFilter).notifier).toggleSelect(note);
12 | }
13 |
14 | /// Selects all the notes.
15 | ///
16 | /// Depending on the current route, selects either the notes from the notes page or those from the bin page.
17 | void selectAllNotes(BuildContext context, WidgetRef ref, {required NoteStatus notesStatus}) {
18 | ref.read(notesProvider(status: notesStatus, label: currentLabelFilter).notifier).setSelectAll(true);
19 | }
20 |
21 | /// Unselects all the notes.
22 | ///
23 | /// Depending on the current route, unselects either the notes from the notes page or those from the bin page.
24 | void unselectAllNotes(BuildContext context, WidgetRef ref, {required NoteStatus notesStatus}) {
25 | ref.read(notesProvider(status: notesStatus, label: currentLabelFilter).notifier).setSelectAll(false);
26 | }
27 |
28 | /// Exits the notes selection mode.
29 | ///
30 | /// First unselects all the notes.
31 | void exitNotesSelectionMode(BuildContext context, WidgetRef ref, {required NoteStatus notesStatus}) {
32 | unselectAllNotes(context, ref, notesStatus: notesStatus);
33 |
34 | isNotesSelectionModeNotifier.value = false;
35 | }
36 |
--------------------------------------------------------------------------------
/lib/common/actions/notes/share.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:share_plus/share_plus.dart';
3 |
4 | import '../../../models/note/note.dart';
5 | import '../../extensions/build_context_extension.dart';
6 |
7 | /// Shares the [note] as text (title and content).
8 | Future shareNote({required Note note}) async {
9 | await SharePlus.instance.share(ShareParams(text: note.shareText, subject: note.title));
10 | }
11 |
12 | /// Shares the [notes] as text (title and content), separated by dashes.
13 | Future shareNotes(BuildContext context, {required List notes}) async {
14 | final text = notes.map((note) => note.shareText).join('\n\n----------\n\n').trim();
15 |
16 | await SharePlus.instance.share(ShareParams(text: text, subject: context.l.action_share_subject(notes.length)));
17 | }
18 |
--------------------------------------------------------------------------------
/lib/common/constants/environment.dart:
--------------------------------------------------------------------------------
1 | /// Environment parameters that can be provided with `--dart-define`.
2 | class Environment {
3 | /// Whether the application should be used to take screenshots for the stores.
4 | static const integrationTest = bool.fromEnvironment('INTEGRATION_TEST');
5 |
6 | /// Whether the application should be used to take screenshots for the stores.
7 | static const screenshots = bool.fromEnvironment('SCREENSHOTS');
8 | }
9 |
--------------------------------------------------------------------------------
/lib/common/constants/labels.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../models/label/label.dart';
4 |
5 | /// Labels used when running integration tests.
6 | final integrationTestLabels = [];
7 |
8 | /// Labels used when taking screenshots of the application for the stores.
9 | final screenshotLabels = [
10 | Label(name: 'Pinned label', colorHex: Colors.red.shade700.toARGB32())..pinned = true,
11 | Label(name: 'Label 1', colorHex: Colors.blue.shade700.toARGB32()),
12 | Label(name: 'Label 2', colorHex: Colors.green.shade700.toARGB32()),
13 | ];
14 |
--------------------------------------------------------------------------------
/lib/common/constants/separators.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | /// Widgets separator.
4 | class Separator extends StatelessWidget {
5 | /// Horizontal separator between two widgets.
6 | const Separator.horizontal({super.key, required this.indent}) : _horizontal = true;
7 |
8 | /// Vertical separator between two widgets.
9 | const Separator.vertical({super.key, required this.indent}) : _horizontal = false;
10 |
11 | /// The start and end indent.
12 | final double indent;
13 |
14 | /// Whether this separator is horizontal.
15 | final bool _horizontal;
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return _horizontal
20 | ? Divider(height: 1, thickness: 1, indent: indent, endIndent: indent)
21 | : VerticalDivider(width: 1, thickness: 1, indent: indent, endIndent: indent);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/common/constants/sizes.dart:
--------------------------------------------------------------------------------
1 | // ignore_for_file: public_member_api_docs
2 |
3 | /// Lists sizes.
4 | enum Sizes {
5 | /// Infinity
6 | infinity(double.infinity),
7 |
8 | /// The size of the icon.
9 | appIcon(64),
10 |
11 | /// The large size of the icon.
12 | appIconLarge(128),
13 |
14 | /// The size of the icon in a settings page when displaying the value of a setting.
15 | settingValueIconSize(16),
16 |
17 | /// The size of small icons.
18 | iconSmall(16),
19 |
20 | /// The size of extra small icons.
21 | iconExtraSmall(12),
22 |
23 | /// The size of the empty placeholder icon.
24 | placeholderIcon(64),
25 |
26 | /// The width of a column in grid layout.
27 | gridLayoutColumnWidth(384),
28 |
29 | /// Height of the labels list in the editor.
30 | editorLabelsListHeight(38),
31 |
32 | /// The height of a button in the editor toolbar.
33 | editorToolbarButtonHeight(42),
34 |
35 | /// The width of a button in the editor toolbar.
36 | editorToolbarButtonWidth(42),
37 |
38 | /// Spacing between the notes tiles in the grid layout.
39 | notesGridLayoutSpacing(8),
40 |
41 | /// Size of the color indicators.
42 | colorIndicator(40),
43 |
44 | /// Padding at the end of the app bars.
45 | appBarEnd(8);
46 |
47 | /// The size to apply.
48 | final double size;
49 |
50 | /// The [size].
51 | const Sizes(this.size);
52 | }
53 |
--------------------------------------------------------------------------------
/lib/common/enums/mime_type.dart:
--------------------------------------------------------------------------------
1 | /// Mime type.
2 | enum MimeType {
3 | /// JSON text files.
4 | json('application/json', 'JSON files', 'json'),
5 |
6 | /// Markdown text files.
7 | markdown('text/markdown', 'Markdown files', 'md'),
8 |
9 | /// ZIP archive files.
10 | zip('application/zip', 'ZIP files', 'zip'),
11 |
12 | /// Log files.
13 | log('text/plain', 'Log files', 'log');
14 |
15 | /// Value of the mime type.
16 | final String value;
17 |
18 | /// Name of the files associated to the [value].
19 | final String label;
20 |
21 | /// Extension of the files associated to the [value].
22 | final String extension;
23 |
24 | /// A mime type with its [value], a [label] and the corresponding file [extension].
25 | const MimeType(this.value, this.label, this.extension);
26 | }
27 |
--------------------------------------------------------------------------------
/lib/common/enums/supported_language.dart:
--------------------------------------------------------------------------------
1 | import 'package:dart_helper_utils/dart_helper_utils.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:locale_names/locale_names.dart';
4 |
5 | /// Languages supported by the application.
6 | enum SupportedLanguage {
7 | /// Czech.
8 | cs(Locale('cs'), 0.89),
9 |
10 | /// English.
11 | en(Locale('en'), 1),
12 |
13 | /// Spanish.
14 | es(Locale('es'), .62),
15 |
16 | /// French.
17 | fr(Locale('fr'), 1),
18 |
19 | /// German.
20 | de(Locale('de'), .79),
21 |
22 | /// Hindi.
23 | hi(Locale('hi'), .52),
24 |
25 | /// Italian.
26 | it(Locale('it'), .61),
27 |
28 | /// Polish.
29 | pl(Locale('pl'), .37),
30 |
31 | /// Portuguese.
32 | pt(Locale('pt'), .54),
33 |
34 | /// Russian.
35 | ru(Locale('ru'), .61),
36 |
37 | /// Turkish.
38 | tr(Locale('tr'), .48),
39 |
40 | /// Chinese Simplified.
41 | zh(Locale('zh'), 1),
42 |
43 | /// Chinese Traditional.
44 | zhTW(Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant'), 1);
45 |
46 | /// The locale completion of this language.
47 | final Locale locale;
48 |
49 | /// The translation completion of this language.
50 | final num completion;
51 |
52 | /// A language supported by the application with its [locale] and its translation [completion].
53 | const SupportedLanguage(this.locale, this.completion);
54 |
55 | /// Returns the list of [locale] supported by the application.
56 | static List locales = values.map((language) => language.locale).toList();
57 |
58 | /// Returns the native name of this language.
59 | String get nativeName => locale.nativeDisplayLanguage.capitalizeFirstLetter;
60 |
61 | /// Returns the translation completion of this language formatted as a percentage according to the [locale].
62 | String get completionFormatted => completion.formatAsPercentage(locale: locale.languageCode);
63 | }
64 |
--------------------------------------------------------------------------------
/lib/common/enums/swipe_direction.dart:
--------------------------------------------------------------------------------
1 | /// Lists the available swipe directions on the notes tiles.
2 | enum SwipeDirection {
3 | /// Swipe to the right.
4 | right,
5 |
6 | /// Swipe to the left.
7 | left,
8 | }
9 |
--------------------------------------------------------------------------------
/lib/common/extensions/build_context_extension.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../l10n/app_localizations/app_localizations.g.dart';
4 |
5 | /// Extensions on the [BuildContext] class.
6 | extension BuildContextExtension on BuildContext {
7 | /// Application localizations.
8 | AppLocalizations get l => AppLocalizations.of(this);
9 |
10 | /// Flutter localizations.
11 | MaterialLocalizations get fl => Localizations.of(this, MaterialLocalizations)!;
12 | }
13 |
--------------------------------------------------------------------------------
/lib/common/extensions/color_extension.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../constants/constants.dart';
3 |
4 | /// Extensions on the [Color] class.
5 | extension ColorExtension on Color {
6 | /// Returns this color but subdued by setting its alpha channel to 150.
7 | Color get subdued => withAlpha(subduedAlpha);
8 | }
9 |
--------------------------------------------------------------------------------
/lib/common/extensions/date_time_extensions.dart:
--------------------------------------------------------------------------------
1 | // ignore_for_file: non_constant_identifier_names
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:intl/intl.dart';
5 |
6 | import 'build_context_extension.dart';
7 |
8 | /// Extends the [DateTime] class with some utilities functions.
9 | extension DateTimeExtensions on DateTime {
10 | /// Returns the date and time formatted to use in a file's name.
11 | ///
12 | /// Pattern: `dd-MM-yyyy_HH-mm-ss`.
13 | String get filename => DateFormat('dd-MM-yyyy_HH-mm-ss').format(this);
14 |
15 | /// Returns the date and time formatted to use in a log file.
16 | ///
17 | /// Pattern: `dd/MM/yyyy - HH:mm:ss`.
18 | String get log => DateFormat('dd/MM/yyyy - HH:mm:ss').format(this);
19 |
20 | /// Returns the date and time formatted in a readable manner, according to the current locale.
21 | ///
22 | /// Pattern: `{date} at {time}`.
23 | String yMMMMd_at_Hm(BuildContext context) {
24 | final localeName = context.l.localeName;
25 |
26 | final date = DateFormat.yMMMMd(localeName).format(this);
27 | final time = DateFormat.Hm(localeName).format(this);
28 |
29 | return '$date ${context.l.about_time_at} $time';
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/common/extensions/iterable_extension.dart:
--------------------------------------------------------------------------------
1 | /// Extends the [Iterable] class with some utilities functions.
2 | extension IterableExtension on Iterable {
3 | /// Returns the enum value for the [name] or `null` if it doesn't exist.
4 | T? byNameOrNull(String? name) {
5 | if (name == null) {
6 | return null;
7 | }
8 |
9 | for (var value in this) {
10 | if (value.name == name) {
11 | return value;
12 | }
13 | }
14 |
15 | return null;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/lib/common/extensions/list_extension.dart:
--------------------------------------------------------------------------------
1 | /// Extends the [List] class with some utilities functions.
2 | extension ListExtension on List {
3 | /// Adds the [item] if it does not already exist in the list, or adds it otherwise.
4 | void addOrUpdate(T item) {
5 | final index = indexOf(item);
6 |
7 | if (index != -1) {
8 | this[index] = item;
9 | } else {
10 | add(item);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/lib/common/extensions/locale_extension.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:intl/intl.dart' as intl;
4 |
5 | import '../system_utils.dart';
6 |
7 | /// Extends the [Locale] class with some utilities functions.
8 | extension LocaleExtension on Locale {
9 | /// Returns the text direction (RTL or LTR) according to the locale of the device (not the locale of the application).
10 | TextDirection get textDirection {
11 | final deviceLanguageCode = SystemUtils().deviceLocale.languageCode;
12 | final textDirection = intl.Bidi.isRtlLanguage(deviceLanguageCode) ? TextDirection.rtl : TextDirection.ltr;
13 |
14 | return textDirection;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lib/common/extensions/string_extension.dart:
--------------------------------------------------------------------------------
1 | /// Extends the [String] class with some utilities functions.
2 | extension StringExtension on String {
3 | /// Returns this string with the first letter capitalized and the rest to lower case.
4 | String get capitalizeFirstLowerRest {
5 | if (trim().length < 2) {
6 | return this;
7 | }
8 |
9 | return '${this[0].toUpperCase()}${substring(1).toLowerCase()}';
10 | }
11 |
12 | /// Returns whether the password is a strong one.
13 | ///
14 | /// A strong password must contain at least:
15 | /// - 1 lowercase
16 | /// - 1 uppercase
17 | /// - 1 number
18 | /// - 1 special character
19 | bool get isStrongPassword {
20 | final regex = RegExp(
21 | r'''^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~`)\%\-(_+=;:,.<>/?"'[{\]}\|^]).{12,}$''',
22 | );
23 |
24 | return regex.hasMatch(this);
25 | }
26 |
27 | /// Returns the encoded URI as decoded.
28 | ///
29 | /// Decodes `:`, `/` and `␣`.
30 | String get decoded {
31 | var uri = this;
32 |
33 | uri = uri.replaceAll('%3A', ':');
34 | uri = uri.replaceAll('%2F', '/');
35 | uri = uri.replaceAll('%20', ' ');
36 |
37 | return uri;
38 | }
39 |
40 | /// Returns the first line of the string.
41 | String? get firstLine => split('\n').firstOrNull;
42 | }
43 |
--------------------------------------------------------------------------------
/lib/common/extensions/text_style_extension.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'color_extension.dart';
3 |
4 | /// Extensions on the [TextStyle] class.
5 | extension TextStyleExtension on TextStyle {
6 | /// Returns this text style but with a subdued color by setting its alpha channel to 150.
7 | TextStyle get subdued => copyWith(color: color?.subdued);
8 | }
9 |
--------------------------------------------------------------------------------
/lib/common/logs/filters/default_filter.dart:
--------------------------------------------------------------------------------
1 | import 'package:logger/logger.dart';
2 |
3 | /// Default log filter.
4 | class DefaultFilter extends LogFilter {
5 | @override
6 | bool shouldLog(LogEvent event) {
7 | return event.level.value >= level!.value;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/common/logs/filters/release_filter.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:logger/logger.dart';
3 |
4 | /// Log filter that only logs messages in release mode.
5 | class ReleaseFilter extends LogFilter {
6 | @override
7 | bool shouldLog(LogEvent event) {
8 | if (!kReleaseMode) {
9 | return false;
10 | }
11 |
12 | return event.level.value >= level!.value;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/lib/common/navigation/app_bars/basic_app_bar.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | /// Basic app bar.
4 | class BasicAppBar extends StatelessWidget {
5 | /// A basic app bar with a title.
6 | const BasicAppBar({super.key, required this.title});
7 |
8 | /// Title to display in the app bar.
9 | final String title;
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return AppBar(title: Text(title));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/lib/common/navigation/app_bars/labels/labels_app_bar.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:gap/gap.dart';
4 |
5 | import '../../../../pages/labels/enums/labels_filter.dart';
6 | import '../../../../providers/labels/labels/labels_provider.dart';
7 | import '../../../../providers/notifiers/notifiers.dart';
8 | import '../../../constants/sizes.dart';
9 | import '../../../extensions/build_context_extension.dart';
10 |
11 | /// Labels app bar.
12 | class LabelsAppBar extends ConsumerStatefulWidget {
13 | /// App bar of the labels page.
14 | const LabelsAppBar({super.key});
15 |
16 | @override
17 | ConsumerState createState() => _LabelsAppBarState();
18 | }
19 |
20 | class _LabelsAppBarState extends ConsumerState {
21 | /// Called when the filter action is pressed.
22 | Future onFilterPressed() async {
23 | await ref.read(labelsProvider.notifier).filter(LabelsFilter.all);
24 |
25 | labelsFiltersNotifier.value = !labelsFiltersNotifier.value;
26 | }
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 | return AppBar(
31 | title: Text(context.l.navigation_manage_labels_page),
32 | actions: [
33 | IconButton(
34 | onPressed: onFilterPressed,
35 | icon: ValueListenableBuilder(
36 | valueListenable: labelsFiltersNotifier,
37 | builder: (context, labelsFilters, child) {
38 | return Icon(labelsFilters ? Icons.filter_list_off : Icons.filter_list);
39 | },
40 | ),
41 | ),
42 | Gap(Sizes.appBarEnd.size),
43 | ],
44 | );
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/lib/common/navigation/enums/editor/editor_archived_menu_option.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../../extensions/build_context_extension.dart';
4 |
5 | /// Lists the options available in the editor's menu for the archived notes.
6 | enum EditorArchivedMenuOption {
7 | /// Copy the notes to the clipboard.
8 | copy(Icons.copy),
9 |
10 | /// Share the notes.
11 | share(Icons.share),
12 |
13 | /// Select the labels of the note.
14 | selectLabels(Icons.label),
15 |
16 | /// Unarchive the note.
17 | unarchive(Icons.unarchive),
18 |
19 | /// Show information about the note.
20 | about(Icons.info);
21 |
22 | /// Icon of the menu option.
23 | final IconData icon;
24 |
25 | /// An option displayed in the menu for the archived notes.
26 | const EditorArchivedMenuOption(this.icon);
27 |
28 | /// Returns the title of the menu option.
29 | String title(BuildContext context) {
30 | switch (this) {
31 | case copy:
32 | return context.fl.copyButtonLabel;
33 | case share:
34 | return context.fl.shareButtonLabel;
35 | case selectLabels:
36 | return context.l.menu_action_select_labels;
37 | case unarchive:
38 | return context.l.action_unarchive;
39 | case about:
40 | return context.l.action_about;
41 | }
42 | }
43 |
44 | /// Returns the [PopupMenuItem] widget of the menu option.
45 | ///
46 | /// Uses the alternative icon if [alternative] is set to `true`.
47 | PopupMenuItem popupMenuItem(BuildContext context) {
48 | return PopupMenuItem(value: this, child: ListTile(leading: Icon(icon), title: Text(title(context))));
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/lib/common/navigation/enums/editor/editor_deleted_menu_option.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../../extensions/build_context_extension.dart';
4 |
5 | /// Lists the options available in the editor's menu for the deleted notes.
6 | enum EditorDeletedMenuOption {
7 | /// Restore the note.
8 | restore(Icons.restore_from_trash),
9 |
10 | /// Permanently delete the note.
11 | ///
12 | /// This action is [dangerous].
13 | deletePermanently(Icons.delete_forever, dangerous: true),
14 |
15 | /// Show information about the note.
16 | about(Icons.info);
17 |
18 | /// Icon of the menu option.
19 | final IconData icon;
20 |
21 | /// Whether the action is a dangerous one.
22 | ///
23 | /// Changes the text and icon colors to red.
24 | final bool dangerous;
25 |
26 | /// An option displayed in the menu for the deleted notes.
27 | ///
28 | /// If [dangerous] is `true`, the icon and the title are shown in red.
29 | const EditorDeletedMenuOption(this.icon, {this.dangerous = false});
30 |
31 | /// Returns the title of the menu option.
32 | String title(BuildContext context) {
33 | switch (this) {
34 | case restore:
35 | return context.l.action_restore;
36 | case deletePermanently:
37 | return context.l.action_delete_permanently;
38 | case about:
39 | return context.l.action_about;
40 | }
41 | }
42 |
43 | /// Returns the [PopupMenuItem] widget of the menu option.
44 | PopupMenuItem popupMenuItem(BuildContext context) {
45 | return PopupMenuItem(
46 | value: this,
47 | child: ListTile(
48 | leading: Icon(icon, color: dangerous ? Theme.of(context).colorScheme.error : null),
49 | title: Text(
50 | title(context),
51 | style: Theme.of(
52 | context,
53 | ).textTheme.titleSmall?.copyWith(color: dangerous ? Theme.of(context).colorScheme.error : null),
54 | ),
55 | ),
56 | );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/lib/common/navigation/enums/notes/selection_archived_menu_option.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../../extensions/build_context_extension.dart';
4 |
5 | /// Lists the options available in the selection menu for the archived notes.
6 | enum SelectionArchivedMenuOption {
7 | /// Copy the notes to the clipboard.
8 | copy(Icons.copy),
9 |
10 | /// Share the notes.
11 | share(Icons.share),
12 |
13 | /// Unarchive the note.
14 | unarchive(Icons.unarchive);
15 |
16 | /// Icon of the menu option.
17 | final IconData icon;
18 |
19 | /// An option displayed in the menu for the archived notes.
20 | ///
21 | /// An action is represented by an [icon] and a [title].
22 | const SelectionArchivedMenuOption(this.icon);
23 |
24 | /// Returns the title of the menu option.
25 | String title(BuildContext context) {
26 | switch (this) {
27 | case copy:
28 | return context.fl.copyButtonLabel;
29 | case share:
30 | return context.fl.shareButtonLabel;
31 | case unarchive:
32 | return context.l.action_unarchive;
33 | }
34 | }
35 |
36 | /// Returns the [PopupMenuItem] widget of the menu option.
37 | ///
38 | /// Uses the alternative icon if [alternative] is set to `true`.
39 | PopupMenuItem popupMenuItem(BuildContext context) {
40 | return PopupMenuItem(value: this, child: ListTile(leading: Icon(icon), title: Text(title(context))));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/common/navigation/enums/notes/selection_available_menu_option.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../../extensions/build_context_extension.dart';
4 |
5 | /// Lists the options available in the selection menu for the available notes.
6 | enum SelectionAvailableMenuOption {
7 | /// Copy the notes to the clipboard.
8 | copy(Icons.copy),
9 |
10 | /// Share the notes.
11 | share(Icons.share),
12 |
13 | /// Toggle whether the notes are pinned.
14 | togglePin(Icons.push_pin),
15 |
16 | /// Toggle whether the notes are locked.
17 | toggleLock(Icons.lock),
18 |
19 | /// Add labels to the notes.
20 | addLabels(Icons.new_label),
21 |
22 | /// Archive the notes.
23 | archive(Icons.archive),
24 |
25 | /// Delete the notes.
26 | delete(Icons.delete);
27 |
28 | /// Icon of the menu option.
29 | final IconData icon;
30 |
31 | /// An option displayed in the menu for the available notes.
32 | ///
33 | /// An action is represented by an [icon] and a [title].
34 | const SelectionAvailableMenuOption(this.icon);
35 |
36 | /// Returns the title of the menu option.
37 | String title(BuildContext context) {
38 | switch (this) {
39 | case copy:
40 | return context.fl.copyButtonLabel;
41 | case share:
42 | return context.fl.shareButtonLabel;
43 | case togglePin:
44 | return context.l.action_toggle_pin;
45 | case toggleLock:
46 | return context.l.action_toggle_lock;
47 | case addLabels:
48 | return context.l.menu_action_add_labels;
49 | case archive:
50 | return context.l.action_archive;
51 | case delete:
52 | return context.l.action_delete;
53 | }
54 | }
55 |
56 | /// Returns the [PopupMenuItem] widget of the menu option.
57 | PopupMenuItem popupMenuItem(BuildContext context) {
58 | return PopupMenuItem(value: this, child: ListTile(leading: Icon(icon), title: Text(title(context))));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/lib/common/navigation/enums/notes/selection_deleted_menu_option.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../../extensions/build_context_extension.dart';
4 |
5 | /// Lists the options available in the selection menu for the deleted notes.
6 | enum SelectionDeletedMenuOption {
7 | /// Restore the note.
8 | restore(Icons.restore_from_trash),
9 |
10 | /// Permanently delete the note.
11 | ///
12 | /// This action is [dangerous].
13 | deletePermanently(Icons.delete_forever, dangerous: true);
14 |
15 | /// Icon of the menu option.
16 | final IconData icon;
17 |
18 | /// Whether the action is a dangerous one.
19 | ///
20 | /// Changes the text and icon colors to red.
21 | final bool dangerous;
22 |
23 | /// An option displayed in the menu for the deleted notes.
24 | ///
25 | /// An action is represented by an [icon] and a [title].
26 | ///
27 | /// If [dangerous] is `true`, the icon and the title are shown in red.
28 | const SelectionDeletedMenuOption(this.icon, {this.dangerous = false});
29 |
30 | /// Returns the title of the menu option.
31 | String title(BuildContext context) {
32 | switch (this) {
33 | case restore:
34 | return context.l.action_restore;
35 | case deletePermanently:
36 | return context.l.action_delete_permanently;
37 | }
38 | }
39 |
40 | /// Returns the [PopupMenuItem] widget of the menu option.
41 | PopupMenuItem popupMenuItem(BuildContext context) {
42 | return PopupMenuItem(
43 | value: this,
44 | child: ListTile(
45 | leading: Icon(icon, color: dangerous ? Theme.of(context).colorScheme.error : null),
46 | title: Text(
47 | title(context),
48 | style: Theme.of(
49 | context,
50 | ).textTheme.titleSmall?.copyWith(color: dangerous ? Theme.of(context).colorScheme.error : null),
51 | ),
52 | ),
53 | );
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/lib/common/navigation/top_navigation.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../models/note/note_status.dart';
4 | import '../../providers/notifiers/notifiers.dart';
5 | import 'app_bars/selection/labels_selection_app_bar.dart';
6 | import 'app_bars/selection/notes_selection_app_bar.dart';
7 |
8 | /// Top navigation with the app bar.
9 | class TopNavigation extends StatelessWidget implements PreferredSizeWidget {
10 | /// Default constructor.
11 | const TopNavigation({super.key, required this.appbar, this.notesStatus});
12 |
13 | /// App bar depending on the current route and whether the selection mode is enabled.
14 | final Widget appbar;
15 |
16 | /// Whether the current page is the notes list.
17 | final NoteStatus? notesStatus;
18 |
19 | @override
20 | Size get preferredSize => const Size.fromHeight(kToolbarHeight);
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | return ValueListenableBuilder(
25 | valueListenable: isNotesSelectionModeNotifier,
26 | builder:
27 | (context, isNotesSelectionMode, child) => ValueListenableBuilder(
28 | valueListenable: isLabelsSelectionModeNotifier,
29 | builder: (context, isLabelsSelectionMode, child) {
30 | if (isNotesSelectionMode && notesStatus != null) {
31 | return NotesSelectionAppBar(notesStatus: notesStatus!);
32 | } else if (isLabelsSelectionMode) {
33 | return const LabelsSelectionAppBar();
34 | }
35 |
36 | return appbar;
37 | },
38 | ),
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/lib/common/preferences/enums/confirmations.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../extensions/build_context_extension.dart';
4 | import '../../extensions/iterable_extension.dart';
5 | import '../preference_key.dart';
6 |
7 | /// Lists the options for the confirmations asked for user actions such as pining and deleting notes.
8 | enum Confirmations {
9 | /// Never ask for a confirmation.
10 | none,
11 |
12 | /// Asks confirmations only for irreversible actions.
13 | irreversible,
14 |
15 | /// Always ask for a confirmation.
16 | all;
17 |
18 | /// The value of the preference if set, or its default value otherwise.
19 | factory Confirmations.fromPreference() {
20 | final confirmations = Confirmations.values.byNameOrNull(PreferenceKey.confirmations.preference);
21 |
22 | // Reset the malformed preference to its default value
23 | if (confirmations == null) {
24 | PreferenceKey.confirmations.reset();
25 |
26 | return Confirmations.values.byName(PreferenceKey.confirmations.defaultValue);
27 | }
28 |
29 | return confirmations;
30 | }
31 |
32 | /// The title of the preference for the settings page.
33 | String title(BuildContext context) {
34 | return switch (this) {
35 | none => context.l.settings_confirmations_title_none,
36 | irreversible => context.l.settings_confirmations_title_irreversible,
37 | all => context.l.settings_confirmations_title_all,
38 | };
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/common/preferences/enums/layout.dart:
--------------------------------------------------------------------------------
1 | import '../../extensions/iterable_extension.dart';
2 | import '../preference_key.dart';
3 |
4 | /// Layout of the notes list.
5 | enum Layout {
6 | /// List view.
7 | list,
8 |
9 | /// Grid view.
10 | grid;
11 |
12 | /// Returns the value of the preference if set, or its default value otherwise.
13 | factory Layout.fromPreference() {
14 | final layout = Layout.values.byNameOrNull(PreferenceKey.layout.preference);
15 |
16 | // Reset the malformed preference to its default value
17 | if (layout == null) {
18 | PreferenceKey.layout.reset();
19 |
20 | return Layout.values.byName(PreferenceKey.layout.defaultValue);
21 | }
22 |
23 | return layout;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/lib/common/preferences/enums/sort_method.dart:
--------------------------------------------------------------------------------
1 | import '../../extensions/iterable_extension.dart';
2 | import '../preference_key.dart';
3 |
4 | /// Sort method of the notes list.
5 | enum SortMethod {
6 | /// Sort according to their creation date.
7 | createdDate,
8 |
9 | /// Sort according to their last edition date.
10 | editedDate,
11 |
12 | /// Sort according to their title.
13 | title,
14 |
15 | /// Sort in ascending order.
16 | ///
17 | /// This is only used to create the [PopupMenuItem] in the sort menu.
18 | ascending;
19 |
20 | /// Returns the value of the preference if set, or its default value otherwise.
21 | factory SortMethod.fromPreference() {
22 | final sortMethod = SortMethod.values.byNameOrNull(PreferenceKey.sortMethod.preference);
23 |
24 | // Reset the malformed preference to its default value
25 | if (sortMethod == null) {
26 | PreferenceKey.sortMethod.reset();
27 |
28 | return SortMethod.values.byName(PreferenceKey.sortMethod.defaultValue);
29 | }
30 |
31 | return sortMethod;
32 | }
33 |
34 | /// Returns whether this sort method is based on a date.
35 | bool get onDate => [createdDate, editedDate].contains(this);
36 | }
37 |
--------------------------------------------------------------------------------
/lib/common/preferences/watched_preferences.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../ui/theme_utils.dart';
4 | import 'enums/font.dart';
5 | import 'enums/layout.dart';
6 | import 'preference_key.dart';
7 |
8 | // ignore_for_file: public_member_api_docs
9 |
10 | /// Watched preferences.
11 | class WatchedPreferences {
12 | // Appearance
13 | late ThemeMode themeMode;
14 | late bool dynamicTheming;
15 | late bool blackTheming;
16 | late Font appFont;
17 |
18 | // Accessibility
19 | late double textScaling;
20 | late bool useWhiteTextDarkMode;
21 |
22 | // Notes
23 | late Layout layout;
24 |
25 | /// Watched preferences with the value passed by the argument if present, or their default value otherwise.
26 | WatchedPreferences({
27 | ThemeMode? themeMode,
28 | bool? dynamicTheming,
29 | bool? blackTheming,
30 | Font? appFont,
31 | double? textScaling,
32 | bool? useWhiteTextDarkMode,
33 | Layout? layout,
34 | }) {
35 | this.themeMode = themeMode ?? ThemeUtils().themeMode;
36 | this.dynamicTheming = dynamicTheming ?? PreferenceKey.dynamicTheming.preferenceOrDefault;
37 | this.blackTheming = blackTheming ?? PreferenceKey.blackTheming.preferenceOrDefault;
38 | this.appFont = appFont ?? Font.appFromPreference();
39 |
40 | this.textScaling = textScaling ?? PreferenceKey.textScaling.preferenceOrDefault;
41 | this.useWhiteTextDarkMode = useWhiteTextDarkMode ?? PreferenceKey.useWhiteTextDarkMode.preferenceOrDefault;
42 |
43 | this.layout = layout ?? Layout.fromPreference();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/lib/common/types.dart:
--------------------------------------------------------------------------------
1 | /// Extra parameters to pass to the editor page.
2 | typedef EditorPageExtra = ({bool readOnly, bool isNewNote});
3 |
--------------------------------------------------------------------------------
/lib/common/ui/snack_bar_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 |
4 | import '../../models/note/types/note_type.dart';
5 | import '../constants/constants.dart';
6 | import '../extensions/build_context_extension.dart';
7 |
8 | /// Utilities for the snack bars.
9 | class SnackBarUtils {
10 | /// Shows a snack bar with the [text].
11 | ///
12 | /// if [error] is `true`, the [text] is prefixed with `Error:`.
13 | ///
14 | /// If [onCancel] is set, an action that calls it when tapped is shown.
15 | void show(
16 | BuildContext context, {
17 | required String text,
18 | bool error = false,
19 | void Function(WidgetRef globalRef)? onCancel,
20 | }) {
21 | if (error) {
22 | text = '${context.l.error_snack_bar} $text';
23 | }
24 |
25 | final availableNotesTypes = NoteType.available;
26 | final behavior = availableNotesTypes.length == 1 ? SnackBarBehavior.floating : SnackBarBehavior.fixed;
27 |
28 | ScaffoldMessenger.of(context).hideCurrentSnackBar();
29 | ScaffoldMessenger.of(context).showSnackBar(
30 | SnackBar(
31 | behavior: behavior,
32 | content: Text(text),
33 | action:
34 | onCancel != null
35 | ? SnackBarAction(label: context.fl.cancelButtonLabel, onPressed: () => onCancel(globalRef))
36 | : null,
37 | ),
38 | );
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/common/widgets/asset.dart:
--------------------------------------------------------------------------------
1 | import 'package:path/path.dart';
2 |
3 | /// Lists the application's assets.
4 | enum Asset {
5 | /// Application's icon.
6 | icon('icons/icon.png');
7 |
8 | /// Base path of the assets.
9 | final _basePath = 'assets';
10 |
11 | /// Path of the asset inside the [_basePath].
12 | final String _filePath;
13 |
14 | /// An asset stored in the assets folder of the application.
15 | ///
16 | /// The asset is accessible with its [path].
17 | const Asset(this._filePath);
18 |
19 | /// Full path of the asset (combination of the [_basePath] and the [_filePath].
20 | String get path => join(_basePath, _filePath);
21 | }
22 |
--------------------------------------------------------------------------------
/lib/common/widgets/labels/label_badge.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:gap/gap.dart';
3 |
4 | import '../../../models/label/label.dart';
5 | import '../../constants/sizes.dart';
6 | import '../../preferences/preference_key.dart';
7 |
8 | /// Badge of a label.
9 | class LabelBadge extends StatelessWidget {
10 | /// A badge displaying the name of a [label] and its color.
11 | const LabelBadge({super.key, required this.label});
12 |
13 | /// The label to display in the badge.
14 | final Label label;
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | final lockLabel = PreferenceKey.lockLabel.preferenceOrDefault;
19 |
20 | return Badge(
21 | label: Row(
22 | children: [
23 | if (lockLabel && label.locked) ...[
24 | Icon(Icons.lock_outline, size: Sizes.iconExtraSmall.size, color: label.getTextColor(context)),
25 | Gap(4),
26 | ],
27 | Expanded(child: Text(label.name, maxLines: 1, overflow: TextOverflow.ellipsis)),
28 | ],
29 | ),
30 | backgroundColor: label.color,
31 | textColor: label.getTextColor(context),
32 | padding: EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0),
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/common/widgets/labels/label_dismissible.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:gap/gap.dart';
4 |
5 | import '../../constants/paddings.dart';
6 | import '../../enums/swipe_direction.dart';
7 | import '../../preferences/enums/swipe_actions/label_swipe_action.dart';
8 |
9 | /// Label tile dismissible widget.
10 | class LabelDismissible extends ConsumerStatefulWidget {
11 | /// Dismissible widget of the label tiles.
12 | const LabelDismissible({super.key, required this.swipeAction, required this.direction});
13 |
14 | /// The swipe action to display.
15 | final LabelSwipeAction swipeAction;
16 |
17 | /// Direction in which the widget can be swiped.
18 | final SwipeDirection direction;
19 |
20 | @override
21 | ConsumerState createState() => _LabelDismissibleState();
22 | }
23 |
24 | class _LabelDismissibleState extends ConsumerState {
25 | @override
26 | Widget build(BuildContext context) {
27 | final iconWidget = widget.swipeAction.iconWidget(context);
28 | final titleWidget = widget.swipeAction.titleWidget(context);
29 |
30 | return ColoredBox(
31 | color: Theme.of(context).colorScheme.tertiaryContainer,
32 | child: Padding(
33 | padding: Paddings.horizontal(16),
34 | child: Row(
35 | mainAxisAlignment: widget.direction == SwipeDirection.right ? MainAxisAlignment.start : MainAxisAlignment.end,
36 | children: [
37 | if (widget.direction == SwipeDirection.right) iconWidget else titleWidget,
38 | Gap(8),
39 | if (widget.direction == SwipeDirection.right) titleWidget else iconWidget,
40 | ],
41 | ),
42 | ),
43 | );
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/lib/common/widgets/labels/label_placeholder_badge.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'label_badge.dart';
4 |
5 | /// Placeholder badge for the labels.
6 | class LabelPlaceholderBadge extends StatelessWidget {
7 | /// A badge similar to the [LabelBadge], but with a neutral color and a [text].
8 | const LabelPlaceholderBadge({super.key, required this.text});
9 |
10 | /// The text to display in the badge.
11 | final String text;
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return Badge(
16 | label: Text(text),
17 | backgroundColor: Theme.of(context).colorScheme.surfaceContainerHighest,
18 | textColor: Theme.of(context).colorScheme.onSurface,
19 | padding: EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0),
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/lib/common/widgets/notes/dismissible/available_dismissible.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:gap/gap.dart';
4 |
5 | import '../../../constants/paddings.dart';
6 | import '../../../enums/swipe_direction.dart';
7 | import '../../../preferences/enums/swipe_actions/available_swipe_action.dart';
8 |
9 | /// Available note tile dismissible widget.
10 | class AvailableDismissible extends ConsumerStatefulWidget {
11 | /// Dismissible widget shown on the note tile of an available note.
12 | const AvailableDismissible({super.key, required this.swipeAction, required this.direction});
13 |
14 | /// The swipe action to display.
15 | final AvailableSwipeAction swipeAction;
16 |
17 | /// Direction in which the widget can be swiped.
18 | final SwipeDirection direction;
19 |
20 | @override
21 | ConsumerState createState() => _AvailableDismissibleState();
22 | }
23 |
24 | class _AvailableDismissibleState extends ConsumerState {
25 | @override
26 | Widget build(BuildContext context) {
27 | final iconWidget = widget.swipeAction.iconWidget(context);
28 | final titleWidget = widget.swipeAction.titleWidget(context);
29 |
30 | return ColoredBox(
31 | color: Theme.of(context).colorScheme.tertiaryContainer,
32 | child: Padding(
33 | padding: Paddings.horizontal(16),
34 | child: Row(
35 | mainAxisAlignment: widget.direction == SwipeDirection.right ? MainAxisAlignment.start : MainAxisAlignment.end,
36 | children: [
37 | if (widget.direction == SwipeDirection.right) iconWidget else titleWidget,
38 | Gap(8),
39 | if (widget.direction == SwipeDirection.right) titleWidget else iconWidget,
40 | ],
41 | ),
42 | ),
43 | );
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/lib/common/widgets/notes/note_tile_labels_list.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 |
4 | import '../../../models/note/note.dart';
5 | import '../labels/label_badge.dart';
6 | import '../labels/label_placeholder_badge.dart';
7 |
8 | /// List of labels on note tiles.
9 | class NoteTileLabelsList extends ConsumerStatefulWidget {
10 | /// The list of labels of the [note] on the note tiles.
11 | const NoteTileLabelsList({super.key, required this.note});
12 |
13 | /// The note for which the labels are displayed.
14 | final Note note;
15 |
16 | @override
17 | ConsumerState createState() => _NoteTileWidgetsState();
18 | }
19 |
20 | class _NoteTileWidgetsState extends ConsumerState {
21 | final maxLabels = 3;
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | final noteLabels = widget.note.labelsVisibleSorted;
26 |
27 | // Wrap with a SizedBox to allow the labels to align to the start of the tile
28 | return SizedBox(
29 | width: double.infinity,
30 | child: Wrap(
31 | spacing: 4.0,
32 | runSpacing: 4.0,
33 | alignment: WrapAlignment.start,
34 | crossAxisAlignment: WrapCrossAlignment.start,
35 | children: [
36 | ...noteLabels.take(maxLabels).map((label) => LabelBadge(label: label)),
37 | if (noteLabels.length > maxLabels) LabelPlaceholderBadge(text: '+ ${noteLabels.length - maxLabels}'),
38 | ],
39 | ),
40 | );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/common/widgets/placeholders/loading_placeholder.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../constants/paddings.dart';
4 |
5 | /// Placeholder widget for loading content.
6 | class LoadingPlaceholder extends StatelessWidget {
7 | /// Default constructor.
8 | const LoadingPlaceholder({super.key});
9 |
10 | @override
11 | Widget build(BuildContext context) {
12 | return Center(
13 | child: Padding(padding: Paddings.page, child: const SingleChildScrollView(child: CircularProgressIndicator())),
14 | );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lib/l10n/translations/app_zh-TW.arb:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/lib/models/deprecated/note.dart:
--------------------------------------------------------------------------------
1 | import 'package:isar/isar.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | import '../label/label.dart';
5 |
6 | part 'note.g.dart';
7 |
8 | // ignore_for_file: must_be_immutable, public_member_api_docs
9 |
10 | List _labelToJson(IsarLinks labels) => labels.map((label) => label.name).toList();
11 |
12 | /// Legacy model of the rich text note.
13 | @JsonSerializable()
14 | @Collection()
15 | @Deprecated('Legacy model of the rich text note')
16 | class Note {
17 | @JsonKey(includeFromJson: false, includeToJson: false)
18 | Id id = Isar.autoIncrement;
19 |
20 | @JsonKey(includeFromJson: false, includeToJson: false)
21 | @ignore
22 | bool selected = false;
23 |
24 | bool deleted;
25 |
26 | bool pinned;
27 |
28 | DateTime createdTime;
29 |
30 | DateTime editedTime;
31 |
32 | String title;
33 |
34 | String content;
35 |
36 | @JsonKey(includeFromJson: false, includeToJson: true, toJson: _labelToJson)
37 | IsarLinks labels = IsarLinks();
38 |
39 | Note({
40 | required this.deleted,
41 | required this.pinned,
42 | required this.createdTime,
43 | required this.editedTime,
44 | required this.title,
45 | required this.content,
46 | });
47 | }
48 |
--------------------------------------------------------------------------------
/lib/models/note/index/note_index.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | import '../note.dart';
4 |
5 | part 'note_index.g.dart';
6 |
7 | /// Notes search index.
8 | @JsonSerializable()
9 | class NoteIndex {
10 | /// The isar ID of the note.
11 | final int id;
12 |
13 | /// Whether the note is deleted.
14 | final bool deleted;
15 |
16 | /// Whether the note is archived.
17 | final bool archived;
18 |
19 | /// The title of the note.
20 | final String title;
21 |
22 | /// The content of the note as plain text.
23 | final String content;
24 |
25 | /// The labels of the note.
26 | final List labels;
27 |
28 | /// A search index for a note, allowing to search through its [title] and [content]
29 | /// and filter on whether it is [deleted], [archived] what [labels] it has.
30 | const NoteIndex({
31 | required this.id,
32 | required this.deleted,
33 | required this.archived,
34 | required this.title,
35 | required this.content,
36 | required this.labels,
37 | });
38 |
39 | /// Creates a [NoteIndex] from a [Note].
40 | factory NoteIndex.fromNote(Note note) => NoteIndex(
41 | id: note.isarId,
42 | deleted: note.deleted,
43 | archived: note.archived,
44 | title: note.title,
45 | content: note.plainText,
46 | labels: note.labelsNamesVisibleSorted,
47 | );
48 |
49 | /// Returns this [NoteIndex] as JSON.
50 | Map toJson() => _$NoteIndexToJson(this);
51 | }
52 |
--------------------------------------------------------------------------------
/lib/models/note/note_status.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../common/extensions/build_context_extension.dart';
4 |
5 | /// The status of a note.
6 | enum NoteStatus {
7 | /// The note is available.
8 | available,
9 |
10 | /// This note is archived.
11 | archived,
12 |
13 | /// The note is deleted.
14 | deleted;
15 |
16 | /// Returns the title of this status.
17 | String title(BuildContext context) {
18 | return switch (this) {
19 | available => context.l.navigation_notes,
20 | archived => context.l.navigation_archives,
21 | deleted => context.l.navigation_bin,
22 | };
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/navigation/navigation_routes.dart:
--------------------------------------------------------------------------------
1 | import '../models/label/label.dart';
2 |
3 | // ignore_for_file: public_member_api_docs
4 |
5 | /// Navigation routes of the application.
6 | enum NavigationRoute {
7 | // Lock
8 | lock('/lock'),
9 |
10 | // Notes
11 | notes('/notes'),
12 | label('label'),
13 | editor('/editor'),
14 |
15 | // Labels
16 | labels('labels'),
17 |
18 | // Archives
19 | archives('archives'),
20 |
21 | // Bin
22 | bin('bin'),
23 |
24 | // Settings
25 | settings('/settings'),
26 | settingsAppearance('appearance'),
27 | settingsNotesTiles('notes-tiles'),
28 | settingsBehavior('behavior'),
29 | settingsNotesTypes('notes-types'),
30 | settingsEditor('editor'),
31 | settingsLabels('labels'),
32 | settingsBackup('backup'),
33 | settingsSecurity('security'),
34 | settingsAccessibility('accessibility'),
35 | settingsHelp('help'),
36 | settingsAbout('about');
37 |
38 | final String path;
39 |
40 | const NavigationRoute(this.path);
41 |
42 | static String getLabelRouteName(Label label) {
43 | final uri = Uri.encodeComponent(label.name);
44 |
45 | return 'label_$uri';
46 | }
47 |
48 | static String getLabelRoutePath(Label label) {
49 | return '${notes.path}/${getLabelRouteName(label)}';
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/lib/pages/archives/archives_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 |
4 | import '../../common/navigation/app_bars/notes/notes_app_bar.dart';
5 | import '../../common/navigation/side_navigation.dart';
6 | import '../../common/navigation/top_navigation.dart';
7 | import '../../common/widgets/notes/notes_list.dart';
8 | import '../../models/note/note_status.dart';
9 |
10 | /// List of archived notes.
11 | class ArchivesPage extends ConsumerStatefulWidget {
12 | /// Default constructor.
13 | const ArchivesPage({super.key});
14 |
15 | @override
16 | ConsumerState createState() => _ArchivesPageState();
17 | }
18 |
19 | class _ArchivesPageState extends ConsumerState {
20 | @override
21 | Widget build(BuildContext context) {
22 | return Scaffold(
23 | appBar: TopNavigation(appbar: NotesAppBar(notesStatus: NoteStatus.archived), notesStatus: NoteStatus.archived),
24 | drawer: SideNavigation(),
25 | body: NotesList(notesStatus: NoteStatus.archived),
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/pages/bin/bin_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 |
4 | import '../../common/navigation/app_bars/notes/notes_app_bar.dart';
5 | import '../../common/navigation/side_navigation.dart';
6 | import '../../common/navigation/top_navigation.dart';
7 | import '../../common/widgets/notes/notes_list.dart';
8 | import '../../models/note/note_status.dart';
9 | import 'widgets/empty_bin_fab.dart';
10 |
11 | /// List of deleted notes.
12 | class BinPage extends ConsumerStatefulWidget {
13 | /// Default constructor.
14 | const BinPage({super.key});
15 |
16 | @override
17 | ConsumerState createState() => _BinPageState();
18 | }
19 |
20 | class _BinPageState extends ConsumerState {
21 | @override
22 | Widget build(BuildContext context) {
23 | return Scaffold(
24 | appBar: TopNavigation(appbar: NotesAppBar(notesStatus: NoteStatus.deleted), notesStatus: NoteStatus.deleted),
25 | drawer: SideNavigation(),
26 | floatingActionButton: EmptyBinFab(),
27 | body: NotesList(notesStatus: NoteStatus.deleted),
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/pages/bin/widgets/empty_bin_fab.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 |
4 | import '../../../common/actions/notes/delete.dart';
5 | import '../../../common/extensions/build_context_extension.dart';
6 | import '../../../common/widgets/placeholders/empty_placeholder.dart';
7 | import '../../../models/note/note_status.dart';
8 | import '../../../providers/notes/notes_provider.dart';
9 |
10 | /// Floating action button to empty the bin.
11 | class EmptyBinFab extends ConsumerWidget {
12 | /// Default constructor.
13 | const EmptyBinFab({super.key});
14 |
15 | @override
16 | Widget build(BuildContext context, WidgetRef ref) {
17 | final deletedNotesCount = ref.watch(notesProvider(status: NoteStatus.deleted)).value?.length;
18 |
19 | return deletedNotesCount != null && deletedNotesCount != 0
20 | ? FloatingActionButton(
21 | tooltip: context.l.tooltip_fab_empty_bin,
22 | onPressed: () => emptyBin(context, ref),
23 | child: const Icon(Icons.delete_forever),
24 | )
25 | : EmptyPlaceholder();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/pages/editor/widgets/editors/checklist_editor.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_checklist/checklist.dart';
3 | import 'package:flutter_riverpod/flutter_riverpod.dart';
4 |
5 | import '../../../../models/note/note.dart';
6 | import '../../../../models/note/note_status.dart';
7 | import '../../../../providers/notes/notes_provider.dart';
8 | import '../../../../providers/notifiers/notifiers.dart';
9 |
10 | /// Checklist editor.
11 | class ChecklistEditor extends ConsumerWidget {
12 | /// Editor allowing to edit the checklist content of a [ChecklistNote].
13 | const ChecklistEditor({super.key, required this.note, required this.isNewNote, required this.readOnly});
14 |
15 | /// The note to display.
16 | final ChecklistNote note;
17 |
18 | /// Whether the note was just created.
19 | final bool isNewNote;
20 |
21 | /// Whether the text fields are read only.
22 | final bool readOnly;
23 |
24 | /// Called when an item of the checklist changes with the new [checklistLines].
25 | void onChecklistChanged(WidgetRef ref, List checklistLines) {
26 | ChecklistNote newNote =
27 | note
28 | ..checkboxes = checklistLines.map((checklistLine) => checklistLine.toggled).toList()
29 | ..texts = checklistLines.map((checklistLine) => checklistLine.text).toList();
30 |
31 | ref.read(notesProvider(status: NoteStatus.available, label: currentLabelFilter).notifier).edit(newNote);
32 | }
33 |
34 | @override
35 | Widget build(BuildContext context, WidgetRef ref) {
36 | return Column(
37 | children: [
38 | Expanded(
39 | child: Checklist(
40 | lines: note.checklistLines,
41 | enabled: !readOnly,
42 | autofocusFirstLine: isNewNote,
43 | onChanged: (checklistLines) => onChecklistChanged(ref, checklistLines),
44 | ),
45 | ),
46 | ],
47 | );
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/lib/pages/editor/widgets/toolbar/horizontal_rule_toolbar_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:fleather/fleather.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | import 'toolbar_button.dart';
5 |
6 | /// Horizontal rule toolbar button.
7 | class HorizontalRuleToolbarButton extends StatelessWidget {
8 | /// Rich text editor toolbar button to add an horizontal rule.
9 | const HorizontalRuleToolbarButton({super.key, required this.fleatherController});
10 |
11 | /// The fleather editor controller.
12 | final FleatherController fleatherController;
13 |
14 | /// Inserts a rule in the content.
15 | void insertHorizontalRule() {
16 | final index = fleatherController.selection.baseOffset;
17 | final length = fleatherController.selection.extentOffset - index;
18 | final newSelection = fleatherController.selection.copyWith(baseOffset: index + 2, extentOffset: index + 2);
19 |
20 | fleatherController.replaceText(index, length, BlockEmbed.horizontalRule, selection: newSelection);
21 | }
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | return ToolbarButton(icon: Icon(Icons.horizontal_rule), onPressed: insertHorizontalRule);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/pages/editor/widgets/toolbar/toolbar_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../../../../common/constants/paddings.dart';
4 | import '../../../../../common/constants/sizes.dart';
5 |
6 | /// Rich text editor custom toolbar button.
7 | class ToolbarButton extends StatelessWidget {
8 | /// Custom button for the toolbar of the rich text editor.
9 | const ToolbarButton({super.key, required this.icon, this.onPressed, this.onLongPress});
10 |
11 | /// Icon of the button.
12 | final Widget icon;
13 |
14 | /// Called when the button is pressed.
15 | final VoidCallback? onPressed;
16 |
17 | /// Called when the button is long-pressed.
18 | final VoidCallback? onLongPress;
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return Padding(
23 | padding: Paddings.horizontal(2),
24 | child: ConstrainedBox(
25 | constraints: BoxConstraints.tightFor(
26 | width: Sizes.editorToolbarButtonHeight.size,
27 | height: Sizes.editorToolbarButtonWidth.size,
28 | ),
29 | child: RawMaterialButton(
30 | shape: const CircleBorder(),
31 | visualDensity: VisualDensity.compact,
32 | elevation: 0,
33 | onPressed: onPressed,
34 | onLongPress: onLongPress,
35 | child: icon,
36 | ),
37 | ),
38 | );
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/pages/labels/enums/labels_filter.dart:
--------------------------------------------------------------------------------
1 | /// Filters for the list of labels.
2 | enum LabelsFilter {
3 | /// Show all labels.
4 | all,
5 |
6 | /// Show only visible labels.
7 | visible,
8 |
9 | /// Show only hidden labels.
10 | hidden,
11 |
12 | /// Show only pinned labels.
13 | pinned,
14 |
15 | /// Show only locked labels.
16 | locked,
17 | }
18 |
--------------------------------------------------------------------------------
/lib/pages/labels/widgets/add_label_fab.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 |
4 | import '../../../common/actions/labels/add.dart';
5 | import '../../../common/extensions/build_context_extension.dart';
6 |
7 | /// FAB to add a label.
8 | class AddLabelFab extends ConsumerWidget {
9 | /// Floating action button to add a new label.
10 | const AddLabelFab({super.key});
11 |
12 | @override
13 | Widget build(BuildContext context, WidgetRef ref) {
14 | return FloatingActionButton(
15 | tooltip: context.l.tooltip_fab_add_label,
16 | onPressed: () => addLabel(context, ref),
17 | child: const Icon(Icons.add),
18 | );
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/lib/pages/settings/widgets/setting_value_text.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../../common/constants/paddings.dart';
4 | import '../../../common/constants/sizes.dart';
5 |
6 | /// Body of a navigation setting tile.
7 | ///
8 | /// Contains:
9 | /// - The [value] of the setting.
10 | /// - An optional [icon].
11 | /// - An optional [description].
12 | ///
13 | /// If the setting tile is not [enabled], the text is shown with a subdued color.
14 | class SettingNavigationTileBody extends StatelessWidget {
15 | /// Default constructor.
16 | const SettingNavigationTileBody({super.key, this.enabled = true, required this.value, this.description, this.icon});
17 |
18 | /// Whether the setting tile is disabled.
19 | final bool enabled;
20 |
21 | /// Value of the setting.
22 | final String value;
23 |
24 | /// Description of the setting.
25 | final String? description;
26 |
27 | /// Icon representing the value of the setting.
28 | final IconData? icon;
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | final titleSmallTextTheme = Theme.of(context).textTheme.titleSmall;
33 | final tertiaryColor = Theme.of(context).colorScheme.tertiary;
34 |
35 | return Column(
36 | crossAxisAlignment: CrossAxisAlignment.start,
37 | children: [
38 | Row(
39 | children: [
40 | if (icon != null) ...[
41 | Icon(icon, size: Sizes.settingValueIconSize.size, color: Theme.of(context).colorScheme.tertiary),
42 | Padding(padding: Paddings.horizontal(2)),
43 | ],
44 | Expanded(
45 | child: Text(
46 | value,
47 | style: titleSmallTextTheme?.copyWith(
48 | color: enabled ? tertiaryColor : titleSmallTextTheme.color?.withAlpha(100),
49 | ),
50 | ),
51 | ),
52 | ],
53 | ),
54 | if (description != null) Text(description!),
55 | ],
56 | );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/lib/providers/labels/labels_list/labels_list_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:collection/collection.dart';
2 | import '../../../common/constants/constants.dart';
3 | import '../../../models/label/label.dart';
4 | import '../../../services/labels/labels_service.dart';
5 | import 'package:riverpod_annotation/riverpod_annotation.dart';
6 |
7 | part 'labels_list_provider.g.dart';
8 |
9 | /// Provider for the labels.
10 | @Riverpod(keepAlive: true)
11 | class LabelsList extends _$LabelsList {
12 | final _labelsService = LabelsService();
13 |
14 | @override
15 | FutureOr> build() => get();
16 |
17 | /// Returns the list of labels.
18 | Future> get() async {
19 | List labels = [];
20 |
21 | try {
22 | labels = await _labelsService.getAll();
23 | } catch (exception, stackTrace) {
24 | logger.e(exception.toString(), exception, stackTrace);
25 | }
26 |
27 | state = AsyncData(labels.sorted());
28 |
29 | return labels.sorted();
30 | }
31 |
32 | /// Returns the label with the [name].
33 | Label getByName(String name) {
34 | assert(state.value != null, 'The value of the labels list provider is null');
35 |
36 | return state.value!.firstWhere((label) => label.name == name);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/providers/notifiers/confirm_exit_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'notifiers.dart';
4 |
5 | /// Confirm exit notifier.
6 | class ConfirmExitNotifier extends ValueNotifier {
7 | /// Notifier for whether the user must confirm to exit the application.
8 | ConfirmExitNotifier(super.value);
9 |
10 | /// Requires the users to confirm within 4 seconds.
11 | void confirm() {
12 | value = true;
13 |
14 | Future.delayed(Duration(seconds: 4), () {
15 | reset();
16 |
17 | canPopNotifier.update();
18 | });
19 |
20 | notifyListeners();
21 | }
22 |
23 | /// Resets the notifier.
24 | void reset() {
25 | value = false;
26 |
27 | notifyListeners();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/providers/notifiers/current_note_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../models/note/note.dart';
4 |
5 | /// Current note notifier.
6 | class CurrentNoteNotifier extends ValueNotifier {
7 | /// Custom notifier for the currently opened note.
8 | CurrentNoteNotifier() : super(null);
9 |
10 | /// The value of the current note.
11 | Note? _value;
12 |
13 | /// Returns the current note.
14 | @override
15 | Note? get value => _value;
16 |
17 | /// Sets the current note to [newNote].
18 | @override
19 | set value(Note? newNote) {
20 | if (newNote == null) {
21 | return;
22 | }
23 |
24 | if (_value == newNote && _value?.labels == newNote.labels) {
25 | return;
26 | }
27 |
28 | _value = newNote;
29 | notifyListeners();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/providers/notifiers/lock_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | /// Page lock notifier.
4 | class LockNotifier extends ValueNotifier {
5 | /// Notifier to lock a page.
6 | LockNotifier(super.value);
7 |
8 | /// Locks the page.
9 | void lock() {
10 | value = true;
11 |
12 | notifyListeners();
13 | }
14 |
15 | /// Unlocks the page.
16 | void unlock() {
17 | value = false;
18 |
19 | notifyListeners();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/lib/providers/notifiers/selection_mode_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../../common/constants/constants.dart';
4 | import '../../common/preferences/preference_key.dart';
5 | import 'notifiers.dart';
6 |
7 | /// Can pop notifier.
8 | class CanPopNotifier extends ValueNotifier {
9 | /// Notifier for whether the routes can be popped.
10 | CanPopNotifier(super.value);
11 |
12 | /// Locks the page.
13 | void update() {
14 | final isNotesSelectionMode = isNotesSelectionModeNotifier.value;
15 | final isLabelsSelectionMode = isLabelsSelectionModeNotifier.value;
16 |
17 | final bool isDrawerOpen =
18 | (notesPageScaffoldKey.currentState?.isDrawerOpen ?? false) ||
19 | (labeledNotesPageScaffoldKey.currentState?.isDrawerOpen ?? false);
20 | final isAddNoteFabOpen =
21 | (addNoteFabKey.currentState?.isOpen ?? false) || (labeledAddNoteFabKey.currentState?.isOpen ?? false);
22 |
23 | final confirmBeforeExiting = PreferenceKey.confirmBeforeExiting.preferenceOrDefault;
24 | final mustConfirmToExit = confirmBeforeExiting ? mustConfirmToExitNotifier.value : true;
25 |
26 | value = !(isNotesSelectionMode || isLabelsSelectionMode || isDrawerOpen || isAddNoteFabOpen || !mustConfirmToExit);
27 |
28 | notifyListeners();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/providers/preferences/preferences_provider.dart:
--------------------------------------------------------------------------------
1 | import '../../common/preferences/watched_preferences.dart';
2 | import 'package:riverpod_annotation/riverpod_annotation.dart';
3 |
4 | part 'preferences_provider.g.dart';
5 |
6 | /// Provider for the preferences.
7 | @Riverpod(keepAlive: true)
8 | class Preferences extends _$Preferences {
9 | @override
10 | WatchedPreferences build() => WatchedPreferences();
11 |
12 | /// Updates the watched preferences with the new [preferences].
13 | void update(WatchedPreferences preferences) {
14 | state = preferences;
15 | }
16 |
17 | /// Resets the watched preferences to their default values.
18 | void reset() {
19 | state = WatchedPreferences();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/lib/services/bin/bin_service.dart:
--------------------------------------------------------------------------------
1 | import '../../common/preferences/preference_key.dart';
2 | import '../notes/notes_service.dart';
3 |
4 | /// Bin service.
5 | class BinService {
6 | final _notesService = NotesService();
7 |
8 | /// Removes the notes from the bin if they have been deleted longer than the corresponding setting, it enabled.
9 | Future removeNotesFromBinIfNeeded() async {
10 | final autoRemoveFromBinDelayPreference = PreferenceKey.autoRemoveFromBinDelay.preferenceOrDefault;
11 | if (autoRemoveFromBinDelayPreference == -1) {
12 | return;
13 | }
14 |
15 | final autoRemoveFromBinDelay = Duration(days: autoRemoveFromBinDelayPreference);
16 | await _notesService.removeFromBin(autoRemoveFromBinDelay);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/lib/services/database_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_mimir/flutter_mimir.dart';
2 | import 'package:isar/isar.dart';
3 | import 'package:path_provider/path_provider.dart';
4 |
5 | import '../models/deprecated/note.dart';
6 | import '../models/label/label.dart';
7 | import '../models/note/note.dart';
8 | import 'bin/bin_service.dart';
9 | import 'labels/labels_service.dart';
10 | import 'migration/migration_service.dart';
11 | import 'notes/notes_index_service.dart';
12 | import 'notes/notes_service.dart';
13 |
14 | /// Abstract service for the database.
15 | ///
16 | /// This class is a singleton.
17 | class DatabaseService {
18 | static final DatabaseService _singleton = DatabaseService._internal();
19 |
20 | /// Default constructor.
21 | factory DatabaseService() => _singleton;
22 |
23 | DatabaseService._internal();
24 |
25 | /// Isar database instance.
26 | late final Isar database;
27 |
28 | /// Mimir index instance.
29 | late final MimirInstance mimir;
30 |
31 | /// Ensures the service is initialized.
32 | Future ensureInitialized() async {
33 | final databaseName = 'materialnotes';
34 | final databaseDirectory = (await getApplicationDocumentsDirectory()).path;
35 |
36 | // Initialize the database
37 | database = await Isar.open(
38 | [NoteSchema, PlainTextNoteSchema, RichTextNoteSchema, MarkdownNoteSchema, ChecklistNoteSchema, LabelSchema],
39 | name: databaseName,
40 | directory: databaseDirectory,
41 | );
42 |
43 | // Initialize mimir
44 | mimir = await Mimir.defaultInstance;
45 |
46 | // Initialize the indexes service
47 | await NotesIndexService().ensureInitialized();
48 |
49 | // Initialize the models services
50 | await LabelsService().ensureInitialized();
51 | await NotesService().ensureInitialized();
52 |
53 | // Perform migrations if needed
54 | await MigrationService().migrateIfNeeded();
55 |
56 | // Remove old notes from the bin if needed
57 | await BinService().removeNotesFromBinIfNeeded();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/makefile:
--------------------------------------------------------------------------------
1 | # Code generation
2 | .PHONY: gen gen_l10n gen_build gen_watch
3 |
4 | gen: gen_l10n gen_build
5 |
6 | gen_l10n:
7 | flutter gen-l10n
8 |
9 | gen_build:
10 | dart run build_runner build --delete-conflicting-outputs
11 |
12 | gen_watch:
13 | dart run build_runner watch --delete-conflicting-outputs
14 |
15 |
16 | # Assets generation
17 | .PHONY: gen_icon gen_splash gen_desc
18 |
19 | gen_icon:
20 | dart run flutter_launcher_icons
21 |
22 | gen_splash:
23 | dart run flutter_native_splash:create
24 |
25 | gen_desc:
26 | py scripts/generate_full_description.py
27 |
28 |
29 | # Build
30 | .PHONY: release release_abi
31 |
32 | release:
33 | flutter build apk --release
34 |
35 | release_abi:
36 | flutter build apk --release --split-per-abi
37 |
38 |
39 | # Update
40 | .PHONY: update_flutter update_fastlane
41 |
42 | update_flutter:
43 | flutter upgrade --force
44 |
45 | update_fastlane:
46 | bundle update fastlane
47 |
48 |
49 | # Miscellaneous
50 | .PHONY: format clean
51 |
52 | format:
53 | dart format .
54 |
55 | clean:
56 | flutter clean
--------------------------------------------------------------------------------
/rust-toolchain.toml:
--------------------------------------------------------------------------------
1 | [toolchain]
2 | channel = "1.83.0"
--------------------------------------------------------------------------------
/scripts/generate_full_description.py:
--------------------------------------------------------------------------------
1 | import minify_html
2 | import os
3 | import yaml
4 |
5 | root = os.getcwd()
6 | path = os.path.join(root, "fastlane/metadata/android")
7 |
8 | for language in os.listdir(path):
9 | if not os.path.isdir(os.path.join(path, language)):
10 | continue
11 |
12 | yaml_filepath = os.path.join(path, language, "full_description.yaml")
13 |
14 | # If the full description is not translated for that language, use the english one
15 | if not os.path.isfile(yaml_filepath):
16 | yaml_filepath = os.path.join(path, "en-US", "full_description.yaml")
17 |
18 | with open(yaml_filepath, mode="r", encoding="utf-8") as yaml_stream:
19 | try:
20 | # Read and minimize the description inside the YAML file
21 | yaml_file = yaml.safe_load(yaml_stream)
22 | full_description = yaml_file["full_description"]
23 | full_description_minified = minify_html.minify(
24 | full_description, keep_closing_tags=True
25 | )
26 |
27 | # Write the description into the text file
28 | text_filepath = os.path.join(path, language, "full_description.txt")
29 | with open(text_filepath, mode="w", encoding="utf-8") as text_file:
30 | text_file.write(full_description_minified)
31 |
32 | print("Generated full_description.txt for language " + language)
33 | except yaml.YAMLError as exception:
34 | print(exception)
35 |
--------------------------------------------------------------------------------
/scripts/isar/fdroid_build_isar.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # Pass no parameters to build libisar for all architectures,
4 | # or pass the desired architectures (x86, x64, armv7, arm64)
5 |
6 | x86() {
7 | echo "Building libisar for x86"
8 |
9 | bash tool/build_android.sh x86
10 |
11 | mv libisar_android_x86.so libisar.so
12 | mv libisar.so "$PUB_CACHE"/hosted/pub.isar-community.dev/isar_flutter_libs-*/android/src/main/jniLibs/x86/
13 | }
14 |
15 | x64() {
16 | echo "Building libisar for x64"
17 |
18 | bash tool/build_android.sh x64
19 |
20 | mv libisar_android_x64.so libisar.so
21 | mv libisar.so "$PUB_CACHE"/hosted/pub.isar-community.dev/isar_flutter_libs-*/android/src/main/jniLibs/x86_64/
22 | }
23 |
24 | armv7() {
25 | echo "Building libisar for armv7"
26 |
27 | bash tool/build_android.sh armv7
28 |
29 | mv libisar_android_armv7.so libisar.so
30 | mv libisar.so "$PUB_CACHE"/hosted/pub.isar-community.dev/isar_flutter_libs-*/android/src/main/jniLibs/armeabi-v7a/
31 | }
32 |
33 | arm64() {
34 | echo "Building libisar for arm64"
35 |
36 | bash tool/build_android.sh arm64
37 |
38 | mv libisar_android_arm64.so libisar.so
39 | mv libisar.so "$PUB_CACHE"/hosted/pub.isar-community.dev/isar_flutter_libs-*/android/src/main/jniLibs/arm64-v8a/
40 | }
41 |
42 | test -d .isar || exit
43 | cp .isar-cargo.lock .isar/Cargo.lock
44 | (
45 | cd .isar || exit
46 | if [ "$#" -eq 0 ]; then
47 | x86
48 | x64
49 | armv7
50 | arm64
51 | else
52 | for arch in "$@"
53 | do
54 | case $arch in
55 | "x86")
56 | x86
57 | ;;
58 | "x64")
59 | x64
60 | ;;
61 | "armv7")
62 | armv7
63 | ;;
64 | "arm64")
65 | arm64
66 | ;;
67 | *)
68 | echo "Invalid architecture: '$arch'"
69 | esac
70 | done
71 | fi
72 | )
73 |
--------------------------------------------------------------------------------
/scripts/isar/fdroid_update_isar.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | isar_version="$(yq -r '.dependencies.isar.version' pubspec.yaml | cut -d '^' -f 2)"
4 | checked_out_version="$(git -C .isar describe --tags)"
5 |
6 | if [ "$isar_version" = "$checked_out_version" ]; then
7 | echo "isar is up-to-date."
8 | exit 0
9 | fi
10 |
11 | echo "Updating from version $checked_out_version to $isar_version."
12 |
13 | git -C .isar checkout "$isar_version"
14 | cargo generate-lockfile --manifest-path .isar/Cargo.toml
15 | mv .isar/Cargo.lock .isar-cargo.lock
--------------------------------------------------------------------------------
/scripts/mimir/fdroid_update_mimir.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | mimir_version="$(yq -r '.dependencies.flutter_mimir' pubspec.yaml | cut -d '^' -f 2)"
4 | checked_out_version="$(git -C .mimir describe --tags)"
5 |
6 | if [ "$mimir_version" = "$checked_out_version" ]; then
7 | echo "mimir is up-to-date."
8 | exit 0
9 | fi
10 |
11 | echo "updating from version $checked_out_version to $mimir_version."
12 |
13 | git -C .mimir checkout flutter_mimir-v"$mimir_version"
14 | cargo generate-lockfile --manifest-path .mimir/Cargo.toml
15 | mv .mimir/Cargo.lock .mimir-cargo.lock
--------------------------------------------------------------------------------