Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ jobs:
run: |
export PUB_CACHE=$HOME/.pub-cache
flutter pub get
sed -i -e 's/-Wl,/-Wl,--build-id=none,/' ${PUB_CACHE}/hosted/*/jni-*/src/CMakeLists.txt
- name: Setup Isar
run: |
sudo apt-get install -y tofrodos
Expand Down Expand Up @@ -138,7 +139,7 @@ jobs:
custom_tag: ${{ needs.get_version.outputs.version }}
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Publish to GitHub releases
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
make_latest: true
name: v${{ needs.get_version.outputs.version }}
Expand Down
3 changes: 1 addition & 2 deletions .run/Generate files.run.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Generate files" type="ShConfigurationType">
<option name="SCRIPT_TEXT"
value="fvm dart run build_runner build --delete-conflicting-outputs" />
<option name="SCRIPT_TEXT" value="fvm dart run build_runner build" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="" />
<option name="SCRIPT_OPTIONS" value="" />
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ 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).

## 2.0.0 - 2026-07-09

### Fixed

- List of notes not updating when (un)deleting and (un)archiving notes
- Rich text note not saving when toggling a checkbox and closing it

### Miscellaneous

- Reduce the APK size

## 2.1.5 - 2026-06-14

### Added
Expand Down
6 changes: 6 additions & 0 deletions fastlane/metadata/android/en-US/changelogs/360.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FIXED
- List of notes not updating when (un)deleting and (un)archiving notes
- Rich text note not saving when toggling a checkbox and closing it

MISCELLANEOUS
- Reduce the APK size
6 changes: 6 additions & 0 deletions fastlane/metadata/android/fr-FR/changelogs/360.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CORRIGÉ
- Les listes des notes ne se mettent pas correctement à jour lors de la suppression/restauration et l'archivage/désarchivage des notes
- Les notes de textes riches ne s'enregistrent pas lorsque qu'une case à cocher est modifiée puis la note fermée

DIVERS
- Réduction de la taille de l'APK
5 changes: 5 additions & 0 deletions lib/common/actions/backup.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import '../../services/backup/auto_backup_service.dart';
Expand All @@ -7,6 +8,10 @@ import '../preferences/preference_key.dart';

/// Requires the user to select a backup directory.
Future<void> requireBackupDirectory(BuildContext context) async {
if (!kReleaseMode) {
return;
}

final select = await showAdaptiveDialog<bool>(
context: context,
useRootNavigator: false,
Expand Down
17 changes: 9 additions & 8 deletions lib/common/actions/notes/archive.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../../models/note/note.dart';
import '../../../models/note/note_status.dart';
import '../../../providers/notes/notes_provider.dart';
import '../../../providers/notifiers/notifiers.dart';
import '../../constants/constants.dart';
Expand Down Expand Up @@ -38,15 +37,16 @@ Future<bool> archiveNote(

currentNoteNotifier.value = null;

final succeeded = await ref
.read(notesProvider(status: NoteStatus.available, label: currentLabelFilter).notifier)
.setArchived([note], true);
final succeeded = await ref.read(notesProvider(status: note.status, label: currentLabelFilter).notifier).setArchived([
note,
], true);

if (succeeded && cancel && context.mounted) {
SnackBarUtils().show(
context,
text: context.l.snack_bar_archived(1),
onCancel: (globalRef) async => await unarchiveNote(context, globalRef, note: note, cancel: false),
onCancel: (globalRef) async =>
await unarchiveNote(rootNavigatorKey.currentContext!, globalRef, note: note, cancel: false),
);
}

Expand All @@ -67,18 +67,19 @@ Future<bool> archiveNotes(BuildContext context, WidgetRef ref, {required List<No
}

final succeeded = await ref
.read(notesProvider(status: NoteStatus.available, label: currentLabelFilter).notifier)
.read(notesProvider(status: notes.first.status, label: currentLabelFilter).notifier)
.setArchived(notes, true);

if (context.mounted) {
exitNotesSelectionMode(context, ref, notesStatus: NoteStatus.available);
exitNotesSelectionMode(context, ref, notesStatus: notes.first.status);
}

if (succeeded && cancel && context.mounted) {
SnackBarUtils().show(
context,
text: context.l.snack_bar_archived(notes.length),
onCancel: (globalRef) async => await unarchiveNotes(context, globalRef, notes: notes, cancel: false),
onCancel: (globalRef) async =>
await unarchiveNotes(rootNavigatorKey.currentContext!, globalRef, notes: notes, cancel: false),
);
}

Expand Down
18 changes: 9 additions & 9 deletions lib/common/actions/notes/delete.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,17 @@ Future<bool> deleteNote(

final wasArchived = note.archived;

final succeeded = await ref
.read(notesProvider(status: NoteStatus.available, label: currentLabelFilter).notifier)
.setDeleted([note], true);
final succeeded = await ref.read(notesProvider(status: note.status, label: currentLabelFilter).notifier).setDeleted([
note,
], true);

if (succeeded && cancel && context.mounted) {
SnackBarUtils().show(
context,
text: context.l.snack_bar_deleted(1),
onCancel: (globalRef) async => wasArchived
? await archiveNote(context, globalRef, note: note, cancel: false)
: await restoreNote(context, globalRef, note: note, cancel: false),
? await archiveNote(rootNavigatorKey.currentContext!, globalRef, note: note, cancel: false)
: await restoreNote(rootNavigatorKey.currentContext!, globalRef, note: note, cancel: false),
);
}

Expand All @@ -74,20 +74,20 @@ Future<bool> deleteNotes(BuildContext context, WidgetRef ref, {required List<Not
final wereArchived = notes.first.archived;

final succeeded = await ref
.read(notesProvider(status: NoteStatus.available, label: currentLabelFilter).notifier)
.read(notesProvider(status: notes.first.status, label: currentLabelFilter).notifier)
.setDeleted(notes, true);

if (context.mounted) {
exitNotesSelectionMode(context, ref, notesStatus: NoteStatus.available);
exitNotesSelectionMode(context, ref, notesStatus: notes.first.status);
}

if (succeeded && cancel && context.mounted) {
SnackBarUtils().show(
context,
text: context.l.snack_bar_deleted(notes.length),
onCancel: (globalRef) async => wereArchived
? await archiveNotes(context, ref, notes: notes)
: await restoreNotes(context, globalRef, notes: notes, cancel: false),
? await archiveNotes(rootNavigatorKey.currentContext!, ref, notes: notes)
: await restoreNotes(rootNavigatorKey.currentContext!, globalRef, notes: notes, cancel: false),
);
}

Expand Down
6 changes: 4 additions & 2 deletions lib/common/actions/notes/restore.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ Future<bool> restoreNote(
SnackBarUtils().show(
context,
text: context.l.snack_bar_restored(1),
onCancel: (globalRef) async => await deleteNote(context, globalRef, note: note, cancel: false),
onCancel: (globalRef) async =>
await deleteNote(rootNavigatorKey.currentContext!, globalRef, note: note, cancel: false),
);
}

Expand Down Expand Up @@ -74,7 +75,8 @@ Future<bool> restoreNotes(BuildContext context, WidgetRef ref, {required List<No
SnackBarUtils().show(
context,
text: context.l.snack_bar_restored(notes.length),
onCancel: (globalRef) async => await deleteNotes(context, globalRef, notes: notes, cancel: false),
onCancel: (globalRef) async =>
await deleteNotes(rootNavigatorKey.currentContext!, globalRef, notes: notes, cancel: false),
);
}

Expand Down
6 changes: 4 additions & 2 deletions lib/common/actions/notes/unarchive.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ Future<bool> unarchiveNote(
SnackBarUtils().show(
context,
text: context.l.snack_bar_unarchived(1),
onCancel: (globalRef) async => await archiveNote(context, globalRef, note: note, cancel: false),
onCancel: (globalRef) async =>
await archiveNote(rootNavigatorKey.currentContext!, globalRef, note: note, cancel: false),
);
}

Expand Down Expand Up @@ -83,7 +84,8 @@ Future<bool> unarchiveNotes(
SnackBarUtils().show(
context,
text: context.l.snack_bar_unarchived(notes.length),
onCancel: (globalRef) async => await archiveNotes(context, globalRef, notes: notes, cancel: false),
onCancel: (globalRef) async =>
await archiveNotes(rootNavigatorKey.currentContext!, globalRef, notes: notes, cancel: false),
);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/models/note/index/note_index.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class NoteIndex {
deleted: note.deleted,
archived: note.archived,
title: note.title,
content: note.plainText,
content: note.contentAsText,
labels: note.labelsNamesVisibleSorted,
);

Expand Down
14 changes: 11 additions & 3 deletions lib/models/note/note.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ sealed class Note implements Comparable<Note> {

/// The content as plain text.
@ignore
String get plainText;
String get contentAsText;

/// The content as markdown.
@ignore
Expand All @@ -131,11 +131,11 @@ sealed class Note implements Comparable<Note> {

/// The number of words in the content.
@ignore
int get wordsCount => _wordsCountRegex.allMatches(plainText).length;
int get wordsCount => _wordsCountRegex.allMatches(contentAsText).length;

/// The number of characters in the content.
@ignore
int get charactersCount => plainText.length;
int get charactersCount => contentAsText.length;

/// Whether the title is empty.
@ignore
Expand Down Expand Up @@ -185,6 +185,14 @@ sealed class Note implements Comparable<Note> {
@ignore
String get labelsAsMarkdown => '> ${labelsNamesVisibleSorted.join(', ')}';

/// The [title] indexed for full-text search.
@Index(type: IndexType.value, caseSensitive: false)
List<String> get titleIndexed => Isar.splitWords(title.toLowerCase());

/// The [contentAsText] indexed for full-text search.
@Index(type: IndexType.value, caseSensitive: false)
List<String> get contentIndexed => Isar.splitWords(contentAsText.toLowerCase());

/// Notes are sorted according to:
/// 1. Their pin state.
/// 2. The sort method chosen by the user.
Expand Down
4 changes: 2 additions & 2 deletions lib/models/note/types/checklist_note.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class ChecklistNote extends Note {

@ignore
@override
String get plainText {
String get contentAsText {
StringBuffer plainText = StringBuffer();

for (int index = 0; index < checkboxes.length; index++) {
Expand Down Expand Up @@ -109,7 +109,7 @@ class ChecklistNote extends Note {

@ignore
@override
String get contentPreview => plainText.trim();
String get contentPreview => contentAsText.trim();

@ignore
@override
Expand Down
4 changes: 2 additions & 2 deletions lib/models/note/types/markdown_note.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ class MarkdownNote extends Note {

@ignore
@override
String get plainText => content.removeMarkdown();
String get contentAsText => content.removeMarkdown();

@ignore
@override
String get contentAsMarkdown => content;

@ignore
@override
String get contentPreview => plainText.trim();
String get contentPreview => contentAsText.trim();

@ignore
@override
Expand Down
4 changes: 2 additions & 2 deletions lib/models/note/types/plain_text_note.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ class PlainTextNote extends Note {

@ignore
@override
String get plainText => content;
String get contentAsText => content;

@ignore
@override
String get contentAsMarkdown => content;

@ignore
@override
String get contentPreview => plainText.trim();
String get contentPreview => contentAsText.trim();

@ignore
@override
Expand Down
2 changes: 1 addition & 1 deletion lib/models/note/types/rich_text_note.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class RichTextNote extends Note {

@ignore
@override
String get plainText => document.toPlainText();
String get contentAsText => document.toPlainText();

@ignore
@override
Expand Down
19 changes: 17 additions & 2 deletions lib/pages/editor/widgets/editors/rich_text_editor.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:convert';

import 'package:fleather/fleather.dart';
Expand Down Expand Up @@ -44,6 +45,15 @@ class RichTextEditor extends ConsumerStatefulWidget {
}

class _RichTextEditorState extends ConsumerState<RichTextEditor> {
late StreamSubscription<ParchmentChange> changes;

@override
void initState() {
super.initState();

changes = widget.fleatherController.document.changes.listen((_) => onChanged());
}

void onLaunchUrl(String? url) {
if (url == null) {
return;
Expand All @@ -68,13 +78,18 @@ class _RichTextEditorState extends ConsumerState<RichTextEditor> {
ref.read(notesProvider(status: NoteStatus.available, label: currentLabelFilter).notifier).edit(note);
}

@override
void dispose() {
changes.cancel();

super.dispose();
}

@override
Widget build(BuildContext context) {
final useParagraphsSpacing = PreferenceKey.useParagraphsSpacing.preferenceOrDefault;
final editorFont = Font.editorFromPreference();

widget.fleatherController.addListener(() => onChanged());

final linkColor = Theme.brightnessOf(context) == Brightness.light ? Colors.blue[800] : Colors.blue[200];

return Padding(
Expand Down
Loading
Loading