Compare commits
10 commits
f91484d6d4
...
45dc458dc5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45dc458dc5 | ||
|
|
1a9513b704 | ||
|
|
1ba414082e | ||
|
|
d6f8f14752 | ||
|
|
01bf1396f8 | ||
|
|
3d7320b614 | ||
|
|
46dcd23419 | ||
|
|
8645c656f2 | ||
|
|
14d6b3c44d | ||
|
|
db13702e54 |
0
.gitignore
vendored
Normal file → Executable file
77
README.md
Normal file → Executable file
|
|
@ -1,16 +1,73 @@
|
|||
# muzzlevelocity
|
||||
> **Migrated to [code.randogoth.com/randogoth/muzzle-velocity](https://code.randogoth.com/randogoth/muzzle-velocity)**
|
||||
|
||||
A new Flutter project.
|
||||
# Muzzle Velocity
|
||||
|
||||
## Getting Started
|
||||
<img src="assets/blaster.svg" width="96" alt="Muzzle Velocity logo">
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
A fast and minimalist but opinionated note-taking app inspired by the legendary *Notational Velocity* on MacOS and *Terminal Velocity* for command line terminals.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
Built for speed and efficiency, eliminating unnecessary UI clutter. Every action should be as fast and frictionless as possible.
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
## Screenshots
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><a href="https://codeberg.org/randogoth/muzzle-velocity/src/branch/main/screenshots/01.jpg" target="_blank"><img src="screenshots/01.jpg" width="180"></a><br><sub>Search with tags</sub></td>
|
||||
<td align="center"><a href="https://codeberg.org/randogoth/muzzle-velocity/src/branch/main/screenshots/02.jpg" target="_blank"><img src="screenshots/02.jpg" width="180"></a><br><sub>View mode</sub></td>
|
||||
<td align="center"><a href="https://codeberg.org/randogoth/muzzle-velocity/src/branch/main/screenshots/03.jpg" target="_blank"><img src="screenshots/03.jpg" width="180"></a><br><sub>Editor menu</sub></td>
|
||||
<td align="center"><a href="https://codeberg.org/randogoth/muzzle-velocity/src/branch/main/screenshots/04.jpg" target="_blank"><img src="screenshots/04.jpg" width="180"></a><br><sub>Preview mode</sub></td>
|
||||
<td align="center"><a href="https://codeberg.org/randogoth/muzzle-velocity/src/branch/main/screenshots/05.jpg" target="_blank"><img src="screenshots/05.jpg" width="180"></a><br><sub>Edit mode</sub></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Features
|
||||
|
||||
**Search & Create** — Type to filter notes by title. Hit Enter on a new title to create it instantly. Search by `#tags`, `+projects`, `@contexts`, or `/folders`. Mix them freely.
|
||||
|
||||
**Gestures**
|
||||
- Swipe right to mark a note as a favorite (swipe right again to remove)
|
||||
- Swipe left to move a note to the trash
|
||||
|
||||
**Editor** — Three modes: View (syntax-highlighted, read-only), Edit, and Preview (rendered Markdown with LaTeX). Autosave, manual save, font size slider, and plain-text sharing from the editor menu.
|
||||
|
||||
**Tags** — Detected automatically from note content. `#tags`, `+projects`, and `@contexts` are all searchable.
|
||||
|
||||
**File Organization** — Notes live in a directory you choose. Subfolders are supported and ordered by most recently modified. Empty folders are cleaned up automatically.
|
||||
|
||||
**Commands** — Type in the search bar and press Enter:
|
||||
|
||||
| Command | Action |
|
||||
|---|---|
|
||||
| `:help` | Open help guide |
|
||||
| `:about` | Open app info |
|
||||
| `:tags` | Toggle tag visibility |
|
||||
| `:fav` | Toggle favorites filter |
|
||||
| `:sub` | Toggle subdirectory search |
|
||||
| `:content` | Toggle file content search |
|
||||
| `:day` | Switch to light theme |
|
||||
| `:night` | Switch to dark theme |
|
||||
| `:extern` | Toggle external editor |
|
||||
| `:intern` | Toggle internal editor |
|
||||
| `:emptytrash` | Permanently delete trashed notes |
|
||||
|
||||
## Download
|
||||
|
||||
Get the latest .apk on the [Release Page](https://codeberg.org/randogoth/muzzle-velocity/releases)
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
flutter build apk --release
|
||||
```
|
||||
|
||||
On systems without Flutter installed, [devbox](https://www.jetify.com/devbox) provides a reproducible environment:
|
||||
|
||||
```sh
|
||||
devbox install
|
||||
devbox shell
|
||||
flutter build apk --release
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Made with 🧡 by randogoth
|
||||
|
|
|
|||
0
android/.gitignore
vendored
Normal file → Executable file
6
assets/blaster.svg
Normal file → Executable file
|
|
@ -15,14 +15,14 @@
|
|||
<g
|
||||
id="g2"
|
||||
transform="matrix(-1,0,0,1,512,0)"
|
||||
style="fill:#ffffff">
|
||||
style="fill:#FF9800">
|
||||
<g
|
||||
id="g1"
|
||||
style="fill:#ffffff">
|
||||
style="fill:#FF9800">
|
||||
<path
|
||||
d="m 466.824,173.176 v -30.118 c 0,-12.475 -10.114,-22.588 -22.588,-22.588 -12.474,0 -22.588,10.114 -22.588,22.588 0,-12.475 -10.114,-22.588 -22.588,-22.588 -12.474,0 -22.588,10.114 -22.588,22.588 0,-12.475 -10.114,-22.588 -22.588,-22.588 -9.83,0 -18.17,6.292 -21.275,15.059 H 90.353 V 90.353 H 45.176 v 45.176 L 0,173.176 v 45.177 l 90.353,97.879 -45.177,30.121 v 75.294 h 90.353 l 43.4,-119.35 30.068,30.068 31.944,-31.944 L 196.522,256 h 136.085 c 3.105,8.767 11.445,15.059 21.275,15.059 12.475,0 22.588,-10.114 22.588,-22.588 0,12.475 10.113,22.588 22.588,22.588 12.475,0 22.588,-10.114 22.588,-22.588 0,12.475 10.113,22.588 22.588,22.588 12.475,0 22.588,-10.114 22.588,-22.588 V 218.353 H 512 V 173.176 Z M 195.765,218.353 H 90.353 v -45.177 h 105.412 z"
|
||||
id="path1"
|
||||
style="fill:#ffffff" />
|
||||
style="fill:#FF9800" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
|
@ -43,7 +43,9 @@ class _WrappedCodeFieldState extends State<WrappedCodeField> {
|
|||
|
||||
@override
|
||||
void dispose() {
|
||||
if (widget.focusNode == null) {
|
||||
_focusNode.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ import 'codefield.dart';
|
|||
|
||||
class NoteEditorScreen extends StatefulWidget {
|
||||
final File note;
|
||||
final String? notesDirectoryPath; // ✅ Add this
|
||||
final String? notesDirectoryPath;
|
||||
final bool isDarkMode;
|
||||
|
||||
final NoteMode initialMode;
|
||||
final bool scrollToEnd;
|
||||
|
||||
const NoteEditorScreen({
|
||||
super.key,
|
||||
|
|
@ -25,6 +25,7 @@ class NoteEditorScreen extends StatefulWidget {
|
|||
required this.isDarkMode,
|
||||
required this.notesDirectoryPath,
|
||||
this.initialMode = NoteMode.view,
|
||||
this.scrollToEnd = false,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -38,6 +39,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
|
|||
late String _initialContent;
|
||||
late NoteMode _mode;
|
||||
final FocusNode _editorFocusNode = FocusNode();
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
bool _isLoading = true;
|
||||
bool _autoSaveEnabled = false;
|
||||
double _fontSize = 16.0;
|
||||
|
|
@ -54,6 +56,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
|
|||
final prefs = await SharedPreferences.getInstance();
|
||||
setState(() {
|
||||
_autoSaveEnabled = prefs.getBool('auto_save_enabled') ?? false;
|
||||
_fontSize = prefs.getDouble('font_size') ?? 16.0;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -82,13 +85,22 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
|
|||
_isLoading = false;
|
||||
});
|
||||
|
||||
if (widget.initialMode == NoteMode.edit) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (widget.initialMode == NoteMode.edit) {
|
||||
_controller.selection =
|
||||
TextSelection.collapsed(offset: _controller.text.length);
|
||||
_editorFocusNode.requestFocus();
|
||||
} else if (widget.scrollToEnd) {
|
||||
// Two frames: first renders content, second has a stable maxScrollExtent.
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToBottom());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _scrollToBottom() {
|
||||
if (_scrollController.hasClients) {
|
||||
_scrollController.jumpTo(_scrollController.position.maxScrollExtent);
|
||||
}
|
||||
}
|
||||
|
||||
void _onTextChanged() {
|
||||
|
|
@ -153,6 +165,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
|
|||
setState(() {
|
||||
_fontSize = newSize;
|
||||
});
|
||||
SharedPreferences.getInstance().then((prefs) => prefs.setDouble('font_size', newSize));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -160,6 +173,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
|
|||
_controller.removeListener(_onTextChanged);
|
||||
_controller.dispose();
|
||||
_editorFocusNode.dispose();
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
@ -208,6 +222,12 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
|
|||
break;
|
||||
case 'Mode Edit':
|
||||
setState(() { _mode = NoteMode.edit; });
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_controller.selection = TextSelection.collapsed(
|
||||
offset: _controller.text.length);
|
||||
_editorFocusNode.requestFocus();
|
||||
_scrollToBottom();
|
||||
});
|
||||
break;
|
||||
case 'Mode Preview':
|
||||
setState(() { _mode = NoteMode.preview; });
|
||||
|
|
@ -362,6 +382,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
|
|||
data: CodeThemeData(
|
||||
styles: widget.isDarkMode ? nightTheme : dayTheme),
|
||||
child: SingleChildScrollView(
|
||||
controller: _scrollController,
|
||||
child: WrappedCodeField(
|
||||
wrap: true,
|
||||
controller: _controller,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ class _NoteListScreenState extends State<NoteListScreen> {
|
|||
bool _includeFileContent = false;
|
||||
bool _includeSubdirectories = true;
|
||||
Timer? _debounce;
|
||||
Set<String> _favorites = {};
|
||||
bool _showOnlyFavorites = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -90,6 +92,23 @@ class _NoteListScreenState extends State<NoteListScreen> {
|
|||
}
|
||||
|
||||
|
||||
Future<void> _saveFavorites() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setStringList('favorites', _favorites.toList());
|
||||
}
|
||||
|
||||
void _toggleFavorite(File note) {
|
||||
setState(() {
|
||||
if (_favorites.contains(note.path)) {
|
||||
_favorites.remove(note.path);
|
||||
} else {
|
||||
_favorites.add(note.path);
|
||||
}
|
||||
});
|
||||
_saveFavorites();
|
||||
_filterNotes();
|
||||
}
|
||||
|
||||
Future<void> _toggleExternalEditor(bool value) async {
|
||||
setState(() {
|
||||
_useExternalEditor = value;
|
||||
|
|
@ -124,6 +143,7 @@ class _NoteListScreenState extends State<NoteListScreen> {
|
|||
defaultDir = dir.path;
|
||||
_useExternalEditor = prefs.getBool('use_external_editor') ?? false;
|
||||
_includeSubdirectories = prefs.getBool('include_subdirectories') ?? true;
|
||||
_favorites = (prefs.getStringList('favorites') ?? []).toSet();
|
||||
});
|
||||
|
||||
notesDirectoryPath = prefs.getString('notes_directory') ?? defaultDir;
|
||||
|
|
@ -149,11 +169,13 @@ class _NoteListScreenState extends State<NoteListScreen> {
|
|||
Welcome to *Muzzle Velocity*.
|
||||
This is your fast and minimal note-taking app.
|
||||
|
||||
1. ✍️ Create Notes quickly: just type a title in the search bar and press enter.
|
||||
2. 🔍 Type keywords to filter notes instantly.
|
||||
3. 💻 Type commands like :help to get more information.
|
||||
4. 🏷️ Use hashtags like #quickstart, context tags like @help, or project tags like +muzzle in your notes for categorization.
|
||||
5. 🔫 Tap the blaster at the top right for more settings or to clear the search field.
|
||||
1. ✍️ **Create** a note: type a title in the search bar and press Enter.
|
||||
2. 🔍 **Search** by title, #tag, +project, @context, or /subfolder.
|
||||
3. ⭐ **Favorite** a note: swipe it to the right.
|
||||
4. 🗑️ **Delete** a note: swipe it to the left.
|
||||
5. 📖 **View / ✏️ Edit / 👁️ Preview**: switch modes from the editor menu.
|
||||
6. 💻 **Commands**: type :help in the search bar for more information.
|
||||
7. 🔫 Tap the blaster at the top right for settings.
|
||||
|
||||
*Muzzle Velocity* is built for speed and simplicity! 🚀
|
||||
|
||||
|
|
@ -326,9 +348,7 @@ Happy note taking! ✨
|
|||
setState(() {
|
||||
if (query.isEmpty) {
|
||||
filteredNotes = List.from(notes);
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
final terms = query.split(' '); // Split search into words
|
||||
final searchTags = terms.where((t) => t.startsWith(RegExp(r'[#@+]'))).toSet();
|
||||
final searchText = terms.where((t) => !t.startsWith(RegExp(r'[#@+]'))).join(' ');
|
||||
|
|
@ -350,6 +370,13 @@ Happy note taking! ✨
|
|||
return (relativePath.contains(normalizedSearch) || content.contains(normalizedSearch)) && matchesTags;
|
||||
}
|
||||
}).toList();
|
||||
}
|
||||
|
||||
if (_showOnlyFavorites) {
|
||||
filteredNotes = filteredNotes
|
||||
.where((note) => _favorites.contains(note.path))
|
||||
.toList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -642,6 +669,16 @@ Happy note taking! ✨
|
|||
case ':intern':
|
||||
_toggleExternalEditor(false);
|
||||
break;
|
||||
case ':fav':
|
||||
setState(() { _showOnlyFavorites = !_showOnlyFavorites; });
|
||||
_filterNotes();
|
||||
break;
|
||||
case ':sub':
|
||||
_toggleIncludeSubdirectories(!_includeSubdirectories);
|
||||
break;
|
||||
case ':content':
|
||||
_toggleIncludeFileContent(!_includeFileContent);
|
||||
break;
|
||||
case ':emptytrash':
|
||||
_confirmEmptyTrash();
|
||||
break;
|
||||
|
|
@ -717,6 +754,10 @@ Happy note taking! ✨
|
|||
),
|
||||
onSelected: (String value) {
|
||||
switch (value) {
|
||||
case 'Toggle Favorites':
|
||||
setState(() { _showOnlyFavorites = !_showOnlyFavorites; });
|
||||
_filterNotes();
|
||||
break;
|
||||
case 'Toggle Tags':
|
||||
widget.toggleTags();
|
||||
break;
|
||||
|
|
@ -744,6 +785,17 @@ Happy note taking! ✨
|
|||
}
|
||||
},
|
||||
itemBuilder: (BuildContext context) => [
|
||||
PopupMenuItem<String>(
|
||||
value: 'Toggle Favorites',
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
_showOnlyFavorites ? Icons.star : Icons.star_outline,
|
||||
color: _showOnlyFavorites ? Colors.amber : null,
|
||||
),
|
||||
title: Text(_showOnlyFavorites ? 'Show All Notes' : 'Show Favorites'),
|
||||
),
|
||||
),
|
||||
PopupMenuDivider(),
|
||||
PopupMenuItem<String>(
|
||||
value: 'Toggle Tags',
|
||||
child: ListTile(
|
||||
|
|
@ -869,16 +921,35 @@ Happy note taking! ✨
|
|||
final noteFile = filteredNotes[index];
|
||||
return Dismissible(
|
||||
key: Key(noteFile.path),
|
||||
direction: DismissDirection.endToStart,
|
||||
direction: DismissDirection.horizontal,
|
||||
background: Container(
|
||||
color: Colors.amber,
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Icon(
|
||||
_favorites.contains(noteFile.path) ? Icons.star_outline : Icons.star,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
secondaryBackground: Container(
|
||||
color: Colors.redAccent,
|
||||
alignment: Alignment.centerRight,
|
||||
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Icon(Icons.delete, color: Colors.white),
|
||||
),
|
||||
confirmDismiss: (direction) async {
|
||||
if (direction == DismissDirection.startToEnd) {
|
||||
_toggleFavorite(noteFile);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
onDismissed: (direction) => _deleteNote(noteFile),
|
||||
child: ListTile(
|
||||
title: Text(noteFile.uri.pathSegments.last.replaceAll('.md', '')),
|
||||
trailing: _favorites.contains(noteFile.path)
|
||||
? Icon(Icons.star, color: Colors.amber, size: 18)
|
||||
: null,
|
||||
subtitle: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final bool hasEnoughSpace = constraints.maxWidth > 200; // Adjust threshold
|
||||
|
|
@ -943,6 +1014,20 @@ Happy note taking! ✨
|
|||
setState(() {}); // ✅ Force UI refresh
|
||||
}
|
||||
},
|
||||
onLongPress: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => NoteEditorScreen(
|
||||
note: noteFile,
|
||||
isDarkMode: widget.isDarkMode,
|
||||
notesDirectoryPath: notesDirectoryPath,
|
||||
scrollToEnd: true,
|
||||
),
|
||||
),
|
||||
);
|
||||
if (context.mounted) _loadNotes();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
|||
87
lib/texts.dart
Normal file → Executable file
|
|
@ -3,76 +3,97 @@ String helpContent = """
|
|||
|
||||
Type to filter notes by title.
|
||||
Use #tags, +projects, or @contexts to find notes with specific tags.
|
||||
Start with a / to filter notes within /subdirectories.
|
||||
Mix text, tags, and folders (/work project #important).
|
||||
Start with a / to filter notes within /folders and /sub/folders.
|
||||
Mix text, tags, and folders freely (/work project #important).
|
||||
|
||||
# Create Notes
|
||||
|
||||
Type the title of a new note in the search bar and hit Enter.
|
||||
Use /folder/note title to create a note inside a subdirectory.
|
||||
Subfolders will be automatically created if they don’t exist.
|
||||
Use /folder/note to create a note inside a subdirectory.
|
||||
Subfolders are automatically created if they don't exist.
|
||||
|
||||
# Delete Notes
|
||||
# Open Notes
|
||||
|
||||
Swipe a note in the list to the left to move it to the trash.
|
||||
The trash is a directory in the root folder.
|
||||
Use :emptytrash or the context menu button to permanently clear deleted notes.
|
||||
**Tap** a note to open it in View mode (syntax-highlighted, read-only).
|
||||
**Long-press** a note to open it scrolled to the end of the file.
|
||||
Switch between View, Edit, and Preview modes from the editor menu.
|
||||
|
||||
# Edit Notes
|
||||
|
||||
Enable/disable autosave in the menu. When disabled you can use the Save button in the menu.
|
||||
If there are unsaved changes when you are leaving the editor, you will be prompted to save.
|
||||
Switch to Edit mode from the editor menu. The cursor is placed at the end.
|
||||
Enable/disable Autosave in the editor menu.
|
||||
When Autosave is off, use the Save button — or you will be prompted on exit.
|
||||
Adjust the font size with the slider in the editor menu.
|
||||
Share a note as plain text from the editor menu.
|
||||
|
||||
# Favorites
|
||||
|
||||
Swipe a note to the **right** to mark it as a favorite (gold star).
|
||||
Swipe right again to remove it from favorites.
|
||||
Use *Show Favorites* in the menu to filter the list to starred notes only.
|
||||
|
||||
# Delete Notes
|
||||
|
||||
Swipe a note to the **left** to move it to the trash.
|
||||
The trash is a directory in the root notes folder.
|
||||
Use :emptytrash or the context menu to permanently clear deleted notes.
|
||||
|
||||
# Tag Notes
|
||||
|
||||
Use tags anywhere in the notes and they will be detected.
|
||||
Use tags anywhere in note content — they are detected automatically.
|
||||
|
||||
#tags – General categorization.
|
||||
+projects – Project-based grouping.
|
||||
@contexts – Context-specific notes.
|
||||
|
||||
Tags must start with a letter and be preceded by a space or line break.
|
||||
|
||||
# Context Menu
|
||||
|
||||
Tap the orange blaster at the top right to open the Preferences.
|
||||
Tap the orange blaster at the top right to open the preferences menu.
|
||||
|
||||
Here you find toggles to show/hide the tags below the note titles and switch between light and dark themes.
|
||||
|
||||
You can also exclude subdirectories from your search.
|
||||
|
||||
By default the search bar filters by note titles, folders, and tags, but you can also toggle including the file contents. Please be aware that this might slow down the app if you have many files.
|
||||
|
||||
If you prefer to use a different Markdown editor for your files you can toggle that and when you tap a file in the list you can choose what to open the file with.
|
||||
|
||||
By default the notes are saved in the App's own directory which is inaccessible to other apps. If you want to choose your own custom folder for this, you can set it. You will be asked for special permissions to do so. This will enable you to save the notes wherever you want, for example to sync them with a different app. You can also choose a folder that already has notes in it.
|
||||
- *Show Favorites / Show All Notes* – Filter the list to starred notes.
|
||||
- *Hide/Show Tags* – Show tag chips below note titles in the list.
|
||||
- *Switch to Light/Dark Mode* – Toggle themes.
|
||||
- *Exclude/Search Subdirectories* – Control the depth of your search.
|
||||
- *Search/Exclude File Content* – Also search inside note content (may slow down the app with many files).
|
||||
- *Use External/Internal Editor* – Open notes in your preferred editor app.
|
||||
- *Set Notes Directory* – Choose a folder anywhere on the device.
|
||||
- *Empty Trash* – Permanently delete all trashed notes.
|
||||
- *Help* – Show this guide.
|
||||
- *About* – App credits and version.
|
||||
|
||||
# File Organization
|
||||
|
||||
Root notes are listed above subfolder notes.
|
||||
Subfolders are ordered by the latest modified file inside them.
|
||||
Empty folders auto-delete after the last file is removed.
|
||||
Empty folders are automatically removed after the last file is deleted.
|
||||
|
||||
# Commands
|
||||
|
||||
Use commands by starting with a colon :
|
||||
Type a colon command in the search bar and press Enter:
|
||||
|
||||
:help – Open this guide.
|
||||
:tags – Toggle tag visibility.
|
||||
:day - Switch to light theme.
|
||||
:night - Switch to dark theme.
|
||||
:extern – Toggle external editor usage.
|
||||
:intern – Toggle internal editor usage.
|
||||
:emptytrash – Permanently delete trashed notes.
|
||||
:about – Open app information.
|
||||
:tags – Toggle tag visibility.
|
||||
:fav – Toggle favorites filter.
|
||||
:sub – Toggle subdirectory search.
|
||||
:content – Toggle file content search.
|
||||
:day – Switch to light theme.
|
||||
:night – Switch to dark theme.
|
||||
:extern – Toggle external editor.
|
||||
:intern – Toggle internal editor.
|
||||
:emptytrash – Permanently delete trashed notes.
|
||||
|
||||
|
||||
""";
|
||||
|
||||
String aboutContent = """
|
||||
**Muzzle Velocity** is a fast and minimalist note-taking app inspired by *Notational Velocity* and *Terminal Velocity*.
|
||||
v.1.1.1
|
||||
|
||||
**Muzzle Velocity** is a fast and minimalist but opinionated note-taking app inspired by the legendary *Notational Velocity* on MacOS and *Terminal Velocity* for command line terminals.
|
||||
|
||||
It is built for speed and efficiency, eliminating unnecessary UI clutter. Every action should be as fast and frictionless as possible.
|
||||
|
||||
Made with 🧡 by randogoth
|
||||
|
||||
with the invaluable help of
|
||||
OpenAI's 🤖 ChatGPT
|
||||
""";
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
name: muzzle_velocity
|
||||
description: "A new Flutter project."
|
||||
description: "A fast and minimalist but opinionated note-taking app inspired by Notational Velocity and Terminal Velocity."
|
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
version: 1.0.0+1
|
||||
version: 1.1.1+3
|
||||
|
||||
environment:
|
||||
sdk: ^3.6.0
|
||||
|
|
|
|||
BIN
screenshots/01.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
screenshots/02.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
screenshots/03.jpg
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
screenshots/04.jpg
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
screenshots/05.jpg
Normal file
|
After Width: | Height: | Size: 39 KiB |