Skip to content

Commit

Permalink
v1.8.0 (#233)
Browse files Browse the repository at this point in the history
* hotfix: generate full descriptions that are not translated with the english one

* hotfix: use documents directory as default auto export directory instead of downloads

* hotfix: avoid using GoRouterState.of(context) when creating a note because it fails with sharing intents

* [237] Untrack generated files (#238)

* hotfix: add back build.yaml

* [250] fix: fail to add a note via share or quick action (#251)

* [247] Improve utils and validators (#252)

* [68] Add support for labels (#245)

* [246] Improve logs (#253)

* [244] Allow to sort by creation date (#254)

* [241] Allow to use white text in dark mode (#255)

* [68] Improve labels (#257)

* Prepare v1.8.0 (#258)
  • Loading branch information
maelchiotti authored Nov 23, 2024
1 parent 388d634 commit f7e36cc
Show file tree
Hide file tree
Showing 149 changed files with 5,254 additions and 8,949 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ jobs:
- name: Add key properties
run: echo "${{ secrets.ANDROID_KEY_PROPERTIES }}" > android/key.properties
- name: Build app
run: flutter build apk --release
run: |
dart run build_runner build
flutter gen-l10n
flutter build apk --release
- name: Archive APK
uses: actions/upload-artifact@v4
with:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/dart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ jobs:
channel: 'stable'
flutter-version-file: pubspec.yaml
- run: |
dart run build_runner build
flutter gen-l10n
flutter pub get
dart analyze --fatal-infos
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ jobs:
- name: Add key properties
run: echo "${{ secrets.ANDROID_KEY_PROPERTIES }}" > android/key.properties
- name: Build app (fat APK)
run: flutter build apk --release
run: |
dart run build_runner build
flutter gen-l10n
flutter build apk --release
- name: Build app (per ABIs)
run: flutter build apk --release --split-per-abi
- name: Create a folder to store the APKs to release
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,7 @@ fastlane/README.md
fastlane/report.xml

# Tests
integration_test/test_bundle.dart
integration_test/test_bundle.dart

# Generated files
*.g.dart
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 1.8.0 - 2024-11-23

### Added

- Ability to categorize the notes with labels
- Allow to sort the notes by their creation date
- Allow to use a white text in dark theme

### Changed

- Improve logs
- Move accessibility settings to their own page

### Fixed

- Failure to add a note via the share action of the quick action

## 1.7.2 - 2024-10-19

### Added
Expand Down
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ Simple, local, material design notes.
- Pin your notes
- Recover your deleted notes from the bin

### Categorize

- Categorize your notes with labels
- Distinguish your labels with their color
- Pin and hide your labels

### Share & backup

- Share text from other applications to add it directly to a note
Expand All @@ -75,14 +81,15 @@ Simple, local, material design notes.

All the supported languages are listed here alphabetically. You can see more details on the [Crowdin project](https://crowdin.com/project/localmaterialnotes). To improve a language or add support for a new one, please see [CONTRIBUTING.md](CONTRIBUTING.md#localization).

![Chinese Simplified](https://img.shields.io/badge/dynamic/json?color=blue&label=Chinese%20Simplified&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27zh-CN%27)].data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-13392640-684950.json)
![English](https://img.shields.io/badge/dynamic/json?color=blue&label=English&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27en%27)].data.approvalProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-13392640-684950.json)
![French](https://img.shields.io/badge/dynamic/json?color=blue&label=French&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27fr%27)].data.approvalProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-13392640-684950.json)
![German](https://img.shields.io/badge/dynamic/json?color=blue&label=German&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27de%27)].data.approvalProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-13392640-684950.json)
![Portuguese](https://img.shields.io/badge/dynamic/json?color=blue&label=Portuguese&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27pt-PT%27)].data.approvalProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-13392640-684950.json)
![Russian](https://img.shields.io/badge/dynamic/json?color=blue&label=Russian&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27ru%27)].data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-13392640-684950.json)
![Spanish](https://img.shields.io/badge/dynamic/json?color=blue&label=Spanish&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27es-ES%27)].data.approvalProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-13392640-684950.json)
![Turkish](https://img.shields.io/badge/dynamic/json?color=blue&label=Turkish&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27tr%27)].data.approvalProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-13392640-684950.json)
- Chinese Simplified
- English
- French
- German
- Polish
- Portuguese
- Russian
- Spanish
- Turkish

## External imports

Expand Down
3 changes: 2 additions & 1 deletion docs/scripts/generate_full_description.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@

yaml_filepath = os.path.join(path, language, "full_description.yaml")

# If the full description is not translated for that language, use the english one
if not os.path.isfile(yaml_filepath):
continue
yaml_filepath = os.path.join(path, "en-US", "full_description.yaml")

with open(yaml_filepath, mode="r", encoding="utf-8") as yaml_stream:
try:
Expand Down
2 changes: 2 additions & 0 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ default_platform(:android)
platform :android do
desc "Build AAB"
lane :build_aab do
sh("dart run build_runner build")
sh("flutter gen-l10n")
sh("flutter build appbundle --release")
end

Expand Down
2 changes: 1 addition & 1 deletion fastlane/metadata/android/de-DE/short_description.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Einfache, lokale Materialdesign-Notiz-App
Einfache, lokale Notizen-App im Material-Design
11 changes: 11 additions & 0 deletions fastlane/metadata/android/en-US/changelogs/170.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ADDED
- Ability to categorize the notes with labels
- Allow to sort the notes by their creation date
- Allow to use a white text in dark theme

CHANGED
- Improve logs
- Move accessibility settings to their own page

FIXED
- Failure to add a note via the share action of the quick action
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions fastlane/metadata/android/fr-FR/changelogs/170.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
AJOUT
- Possibilité de catégoriser les notes avec des étiquettes
- Possibilité de trier les notes en fonction de leur date de création
- Possibilité d'utiliser un texte blanc avec le thème sombre

MODIFIÉ
- Amélioration des logs
- Déplacement des paramètres d'accessibilité vers leur propre page

CORRIGÉ
- Échec de l'ajout d'une note via l'action de partage ou l'action rapide de l'écran d'accueil
2 changes: 1 addition & 1 deletion fastlane/metadata/android/pl-PL/short_description.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Simple, local, material design notes
Proste, lokalne notatki w stylu Material Design
9 changes: 3 additions & 6 deletions fastlane/metadata/android/tr-TR/full_description.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
full_description: |
<p>
<b>Materyal Not</b> basitliği hedefleyen, metin tabanlı bir not alma uygulamasıdır. Materyal Tasarımı'nı benimser.
Notları yerel olarak depolar ve herhangi bir internet iznine sahip değildir, bu nedenle notlara erişebilen tek kişi
sizsiniz.
Notları yerel olarak depolar ve herhangi bir internet iznine sahip değildir, bu nedenle notlara erişebilen tek kişi sizsiniz.
</p>
<p>
Expand Down Expand Up @@ -40,8 +39,7 @@ full_description: |
<b>Koruma</b>
</p>
<ul>
<li>Verilerinizin nasıl işlendiği konusunda asla endişelenmeyin: uygulama internet izinlerine sahip olmadığı için
cihazınızdan ayrılamaz</li>
<li>Verilerinizin nasıl işlendiği konusunda asla endişelenmeyin: uygulama internet izinlerine sahip olmadığı için cihazınızdan ayrılamaz</li>
<li>JSON dışa aktarımlarınızı şifreleyin</li>
</ul>
Expand All @@ -52,7 +50,6 @@ full_description: |
<li>Dilinizi seçin</li>
<li>Temanızı seçin (açık, koyu veya siyah)</li>
<li>Temanızın dinamik olup olmayacağını seçin (arkaplanınızdan renkler kullanın)</li>
<li>Gelişmiş biçimlendirmeyi, yalnızca kontrol listelerini mi yoksa notlarınızı temel tutmak isteyip istemediğinizi
seçin
<li>Gelişmiş biçimlendirmeyi, yalnızca kontrol listelerini mi yoksa notlarınızı temel tutmak isteyip istemediğinizi seçin
</li>
</ul>
2 changes: 2 additions & 0 deletions integration_test/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:localmaterialnotes/common/preferences/preferences_utils.dart';
import 'package:localmaterialnotes/routing/routes/bin/bin_route.dart';
import 'package:localmaterialnotes/routing/routes/settings/settings_route.dart';
import 'package:localmaterialnotes/routing/routes/shell/shell_route.dart';
import 'package:localmaterialnotes/services/labels/labels_service.dart';
import 'package:localmaterialnotes/services/notes/notes_service.dart';
import 'package:localmaterialnotes/utils/auto_export_utils.dart';
import 'package:localmaterialnotes/utils/flag_secure_utils.dart';
Expand All @@ -26,6 +27,7 @@ Future<Widget> get app async {

// Initialize the services
await NotesService().ensureInitialized();
await LabelsService().ensureInitialized();

// No need to await this, it can be performed in the background
AutoExportUtils().ensureInitialized();
Expand Down
62 changes: 36 additions & 26 deletions lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import 'package:localmaterialnotes/common/constants/constants.dart';
import 'package:localmaterialnotes/common/extensions/locale_extension.dart';
import 'package:localmaterialnotes/common/widgets/placeholders/error_placeholder.dart';
import 'package:localmaterialnotes/l10n/app_localizations/app_localizations.g.dart';
import 'package:localmaterialnotes/providers/labels/labels_list/labels_list_provider.dart';
import 'package:localmaterialnotes/providers/labels/labels_navigation/labels_navigation_provider.dart';
import 'package:localmaterialnotes/providers/notifiers.dart';
import 'package:localmaterialnotes/routing/router.dart';
import 'package:localmaterialnotes/utils/locale_utils.dart';
Expand Down Expand Up @@ -35,6 +37,10 @@ class _AppState extends ConsumerState<App> with AfterLayoutMixin<App> {
// Read the potential data shared from other applications
readSharedData(ref);
_stream = listenSharedData(ref);

// Eagerly get the labels for the full list and the navigation
ref.read(labelsListProvider.notifier).get();
ref.read(labelsNavigationProvider.notifier).get();
}

@override
Expand Down Expand Up @@ -66,35 +72,39 @@ class _AppState extends ConsumerState<App> with AfterLayoutMixin<App> {
return ValueListenableBuilder(
valueListenable: textScalingNotifier,
builder: (context, textScaling, child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaler: TextScaler.linear(textScaling),
),
child: MaterialApp.router(
title: 'Material Notes',
routerConfig: router,
builder: (context, child) {
// Change the widget shown when a widget building fails
ErrorWidget.builder = (errorDetails) => ErrorPlaceholder.errorDetails(errorDetails);
return ValueListenableBuilder(
valueListenable: useWhiteTextDarkModeNotifier,
builder: (context, useWhiteTextDarkMode, child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaler: TextScaler.linear(textScaling),
),
child: MaterialApp.router(
title: 'Material Notes',
routerConfig: router,
builder: (context, child) {
// Change the widget shown when a widget building fails
ErrorWidget.builder = (errorDetails) => ErrorPlaceholder.errorDetails(errorDetails);

if (child == null) {
throw StateError('MaterialApp child is null');
}
if (child == null) {
throw StateError('MaterialApp child is null');
}

return Directionality(
textDirection: LocaleUtils().deviceLocale.textDirection,
child: child,
return Directionality(
textDirection: LocaleUtils().deviceLocale.textDirection,
child: child,
);
},
theme: ThemeUtils().getLightTheme(lightDynamicColorScheme),
darkTheme: ThemeUtils().getDarkTheme(darkDynamicColorScheme, useWhiteTextDarkMode),
themeMode: themeMode,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: LocaleUtils().appLocale,
debugShowCheckedModeBanner: false,
),
);
},
theme: ThemeUtils().getLightTheme(lightDynamicColorScheme),
darkTheme: ThemeUtils().getDarkTheme(darkDynamicColorScheme),
themeMode: themeMode,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: LocaleUtils().appLocale,
debugShowCheckedModeBanner: false,
),
);
});
},
);
},
Expand Down
22 changes: 22 additions & 0 deletions lib/common/actions/labels/add.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:localmaterialnotes/common/constants/constants.dart';
import 'package:localmaterialnotes/models/label/label.dart';
import 'package:localmaterialnotes/pages/labels/dialogs/label_dialog.dart';
import 'package:localmaterialnotes/providers/labels/labels/labels_provider.dart';

/// Adds a label.
Future<void> addLabel(BuildContext context, WidgetRef ref) async {
final label = await showAdaptiveDialog<Label>(
context: context,
builder: (context) {
return LabelDialog(title: l.dialog_label_add);
},
);

if (label == null) {
return;
}

ref.read(labelsProvider.notifier).edit(label);
}
64 changes: 64 additions & 0 deletions lib/common/actions/labels/delete.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// ignore_for_file: unused_import

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:localmaterialnotes/common/actions/labels/select.dart';
import 'package:localmaterialnotes/common/actions/notes/select.dart';
import 'package:localmaterialnotes/common/constants/constants.dart';
import 'package:localmaterialnotes/common/dialogs/confirmation_dialog.dart';
import 'package:localmaterialnotes/common/extensions/build_context_extension.dart';
import 'package:localmaterialnotes/models/label/label.dart';
import 'package:localmaterialnotes/models/note/note.dart';
import 'package:localmaterialnotes/providers/bin/bin_provider.dart';
import 'package:localmaterialnotes/providers/labels/labels/labels_provider.dart';
import 'package:localmaterialnotes/providers/notes/notes/notes_provider.dart';
import 'package:localmaterialnotes/providers/notifiers.dart';
import 'package:localmaterialnotes/routing/routes/notes/notes_editor_route.dart';
import 'package:localmaterialnotes/routing/routes/shell/shell_route.dart';

/// Deletes the [label].
///
/// Returns `true` if the [label] was deleted, `false` otherwise.
///
/// First, asks for a confirmation if needed.
Future<bool> deleteLabel(BuildContext context, WidgetRef ref, Label? label) async {
if (label == null) {
return false;
}

if (!await askForConfirmation(
context,
l.dialog_delete,
l.dialog_delete_body(1),
l.dialog_delete,
)) {
return false;
}

return await ref.read(labelsProvider.notifier).delete(label);
}

/// Deletes the [labels].
///
/// Returns `true` if the [labels] were deleted, `false` otherwise.
///
/// First, asks for a confirmation if needed.
Future<bool> deleteLabels(BuildContext context, WidgetRef ref, List<Label> labels) async {
if (!await askForConfirmation(
context,
l.dialog_delete,
l.dialog_delete_body(labels.length),
l.dialog_delete,
)) {
return false;
}

final succeeded = await ref.read(labelsProvider.notifier).deleteAll(labels);

if (context.mounted) {
exitLabelsSelectionMode(ref);
}

return succeeded;
}
Loading

0 comments on commit f7e36cc

Please sign in to comment.