Log every feature and how we reach the purchase page

We now have a list of all the features that are implemented, and we can
use that to show a kind of feature list which can be used to -

1. Move away from app rental model
2. Showcase a feature list; see WorkingCopy
This commit is contained in:
Vishesh Handa
2020-08-10 16:05:26 +02:00
parent b82b5ee658
commit c048ead8a9
10 changed files with 275 additions and 32 deletions

View File

@ -180,7 +180,7 @@ features:
noteMetaDataCustomize: noteMetaDataCustomize:
title: Customize Note Metadata title: Customize Note Metadata
subtitle: Allows GitJorunal to be used with static website generators subtitle: Allows GitJorunal to be used with static website generators
autoMergeConflict: Automation Merge Conflict Resolution autoMergeConflicts: Automation Merge Conflict Resolution
noteSorting: Configurable Note Sorting noteSorting: Configurable Note Sorting
gitPushFreq: Configurable Git Sync Frequency gitPushFreq: Configurable Git Sync Frequency
checklistEditor: Checklist Editor checklistEditor: Checklist Editor
@ -194,3 +194,9 @@ features:
txtFiles: Txt File Support txtFiles: Txt File Support
wikiLinks: Wiki Style Links Support wikiLinks: Wiki Style Links Support
metaDataTitle: Customize Title MetaData metaDataTitle: Customize Title MetaData
journalEditorDefaultFolder: Customize Default Folder for Journal Editor
yamlModifiedKey: Customize the YAML modified key
yamlCreatedKey: Customize the YAML created key
yamlTagsKey: Customize the YAML tags key
disableYamlHeader: Disable YAML Metadata Header
customizeHomeScreen: Customize Home Screen

View File

@ -12,6 +12,7 @@ import 'package:share/share.dart';
import 'package:gitjournal/core/note.dart'; import 'package:gitjournal/core/note.dart';
import 'package:gitjournal/core/notes_folder_fs.dart'; import 'package:gitjournal/core/notes_folder_fs.dart';
import 'package:gitjournal/error_reporting.dart'; import 'package:gitjournal/error_reporting.dart';
import 'package:gitjournal/features.dart';
import 'package:gitjournal/widgets/pro_overlay.dart'; import 'package:gitjournal/widgets/pro_overlay.dart';
export 'package:gitjournal/editors/scaffold.dart'; export 'package:gitjournal/editors/scaffold.dart';
@ -250,6 +251,7 @@ Widget _buildBottomMenuSheet(
}, },
), ),
ProOverlay( ProOverlay(
feature: Feature.tags,
child: ListTile( child: ListTile(
leading: const FaIcon(FontAwesomeIcons.tag), leading: const FaIcon(FontAwesomeIcons.tag),
title: Text(tr('editors.common.tags')), title: Text(tr('editors.common.tags')),
@ -272,6 +274,7 @@ Widget _buildBottomMenuSheet(
}, },
), ),
ProOverlay( ProOverlay(
feature: Feature.zenMode,
child: ListTile( child: ListTile(
leading: const FaIcon(FontAwesomeIcons.peace), leading: const FaIcon(FontAwesomeIcons.peace),
title: Text(tr(zenModeEnabled title: Text(tr(zenModeEnabled

View File

@ -4,40 +4,249 @@ class Features {
static bool perFolderConfig = false; static bool perFolderConfig = false;
static final all = <Feature>[ static final all = <Feature>[
Feature(DateTime(2019, 09, 25), tr("feature.darkMode"), "", false), Feature.darkMode,
Feature(DateTime(2019, 10, 07), tr("feature.rawEditor"), "", false), Feature.rawEditor,
Feature(DateTime(2019, 12, 04), tr("feature.folderSupport"), "", false), Feature.folderSupport,
Feature(DateTime(2019, 12, 20), tr("feature.fileNameCustomize"), "", false), Feature.fileNameCustomize,
Feature( Feature.noteMetaDataCustomize,
DateTime(2019, 12, 20), Feature.autoMergeConflicts,
tr("feature.noteMetaDataCustomize.title"), Feature.yamlModifiedKey,
tr("feature.noteMetaDataCustomize.subtitle"), Feature.noteSorting,
true, Feature.gitPushFreq,
), Feature.checkListEditor,
Feature(DateTime(2019, 12, 28), tr("feature.autoMergeConflict"), "", false), Feature.disableYamlHeader,
Feature(DateTime(2020, 02, 09), tr("feature.noteSorting"), "", false), Feature.journalEditor,
Feature(DateTime(2020, 02, 09), tr("feature.noteSorting"), "", false), Feature.diffViews,
Feature(DateTime(2020, 02, 09), tr("feature.gitPushFreq"), "", false), Feature.journalEditorDefaultFolder,
Feature(DateTime(2020, 02, 15), tr("feature.checklistEditor"), "", false), Feature.customizeHomeScreen,
Feature(DateTime(2020, 03, 01), tr("feature.journalEditor"), "", false), Feature.imageSupport,
Feature(DateTime(2020, 04, 01), tr("feature.diffViews"), "", false), Feature.tags,
Feature(DateTime(2020, 05, 08), tr("feature.imageSupport"), "", false), Feature.appShortcuts,
Feature(DateTime(2020, 05, 14), tr("feature.tags"), "", true), Feature.createRepo,
Feature(DateTime(2020, 05, 14), tr("feature.appShortcuts"), "", false), Feature.backlinks,
Feature(DateTime(2020, 05, 18), tr("feature.createRepo"), "", false), Feature.txtFiles,
Feature(DateTime(2020, 05, 27), tr("feature.backlinks"), "", true), Feature.wikiLinks,
Feature(DateTime(2020, 06, 03), tr("feature.txtFiles"), "", false), Feature.zenMode,
Feature(DateTime(2020, 07, 09), tr("feature.wikiLinks"), "", false), Feature.metaDataTitle,
Feature(DateTime(2020, 07, 28), tr("feature.zenMode"), "", true), Feature.yamlCreatedKey,
Feature(DateTime(2020, 07, 30), tr("feature.metaDataTitle"), "", true), Feature.yamlTagsKey,
]; ];
} }
class Feature { class Feature {
final String featureName;
final DateTime date; final DateTime date;
final String title; final String title;
final String subtitle; final String subtitle;
final bool pro; final bool pro;
Feature(this.date, this.title, this.subtitle, this.pro); Feature(this.featureName, this.date, this.title, this.subtitle, this.pro);
static final darkMode = Feature(
"DarkMode",
DateTime(2019, 09, 25),
tr("feature.darkMode"),
"",
false,
);
static final rawEditor = Feature(
"RawEditor",
DateTime(2019, 10, 07),
tr("feature.rawEditor"),
"",
false,
);
static final folderSupport = Feature(
"FolderSupport",
DateTime(2019, 12, 04),
tr("feature.folderSupport"),
"",
false,
);
static final fileNameCustomize = Feature(
"FileNameCustomize",
DateTime(2019, 12, 20),
tr("feature.fileNameCustomize"),
"",
false,
);
static final noteMetaDataCustomize = Feature(
"NoteMetaDataCustomize",
DateTime(2019, 12, 20),
tr("feature.noteMetaDataCustomize.title"),
tr("feature.noteMetaDataCustomize.subtitle"),
true,
);
static final autoMergeConflicts = Feature(
"AutoMergeConflicts",
DateTime(2019, 12, 28),
tr("feature.autoMergeConflicts"),
"",
false,
);
static final yamlModifiedKey = Feature(
"YamlModifiedKey",
DateTime(2020, 01, 05),
tr("feature.yamlModifiedKey"),
"",
true,
);
static final noteSorting = Feature(
"NoteSorting",
DateTime(2020, 02, 09),
tr("feature.noteSorting"),
"",
false,
);
static final gitPushFreq = Feature(
"GitPushFreq",
DateTime(2020, 02, 09),
tr("feature.gitPushFreq"),
"",
false,
);
static final checkListEditor = Feature(
"CheckListEditor",
DateTime(2020, 02, 15),
tr("feature.checklistEditor"),
"",
false,
);
static final disableYamlHeader = Feature(
"DisableYamlHeader",
DateTime(2020, 02, 18),
tr("feature.disableYamlHeader"),
"",
false,
);
static final journalEditor = Feature(
"JournalEditor",
DateTime(2020, 03, 01),
tr("feature.journalEditor"),
"",
false,
);
static final diffViews = Feature(
"DiffViews",
DateTime(2020, 04, 01),
tr("feature.diffViews"),
"",
false,
);
static final journalEditorDefaultFolder = Feature(
"JournalEditorDefaultFolder",
DateTime(2020, 04, 01),
tr("feature.journalEditorDefaultFolder"),
"",
true,
);
static final customizeHomeScreen = Feature(
"CustomizeHomeScreen",
DateTime(2020, 05, 06),
tr("feature.customizeHomeScreen"),
"",
true,
);
static final imageSupport = Feature(
"ImageSupport",
DateTime(2020, 05, 08),
tr("feature.imageSupport"),
"",
false,
);
static final tags = Feature(
"Tags",
DateTime(2020, 05, 14),
tr("feature.tags"),
"",
true,
);
static final appShortcuts = Feature(
"AppShortcuts",
DateTime(2020, 05, 14),
tr("feature.appShortcuts"),
"",
false,
);
static final createRepo = Feature(
"CreateRepo",
DateTime(2020, 05, 18),
tr("feature.createRepo"),
"",
false,
);
static final backlinks = Feature(
"Backlinks",
DateTime(2020, 05, 27),
tr("feature.backlinks"),
"",
true,
);
static final txtFiles = Feature(
"TxtFiles",
DateTime(2020, 06, 03),
tr("feature.txtFiles"),
"",
false,
);
static final wikiLinks = Feature(
"WikiLinks",
DateTime(2020, 07, 09),
tr("feature.wikiLinks"),
"",
false,
);
static final zenMode = Feature(
"ZenMode",
DateTime(2020, 07, 28),
tr("feature.zenMode"),
"",
true,
);
static final metaDataTitle = Feature(
"MetaDataTitle",
DateTime(2020, 07, 30),
tr("feature.metaDataTitle"),
"",
true,
);
static final yamlCreatedKey = Feature(
"YamlCreatedKey",
DateTime(2020, 08, 02),
tr("feature.yamlCreatedKey"),
"",
true,
);
static final yamlTagsKey = Feature(
"yamlTagsKey",
DateTime(2020, 08, 06),
tr("feature.yamlTagsKey"),
"",
true,
);
} }

View File

@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:gitjournal/core/notes_folder_fs.dart'; import 'package:gitjournal/core/notes_folder_fs.dart';
import 'package:gitjournal/features.dart';
import 'package:gitjournal/screens/settings_screen.dart'; import 'package:gitjournal/screens/settings_screen.dart';
import 'package:gitjournal/screens/settings_widgets.dart'; import 'package:gitjournal/screens/settings_widgets.dart';
import 'package:gitjournal/settings.dart'; import 'package:gitjournal/settings.dart';
@ -63,6 +64,7 @@ class SettingsEditorsScreenState extends State<SettingsEditorsScreen> {
), ),
SettingsHeader(tr("settings.editors.journalEditor")), SettingsHeader(tr("settings.editors.journalEditor")),
ProOverlay( ProOverlay(
feature: Feature.journalEditorDefaultFolder,
child: ListTile( child: ListTile(
title: Text(tr("settings.editors.defaultFolder")), title: Text(tr("settings.editors.defaultFolder")),
subtitle: Text(defaultNewFolder), subtitle: Text(defaultNewFolder),

View File

@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:gitjournal/core/notes_folder_fs.dart'; import 'package:gitjournal/core/notes_folder_fs.dart';
import 'package:gitjournal/features.dart';
import 'package:gitjournal/screens/settings_widgets.dart'; import 'package:gitjournal/screens/settings_widgets.dart';
import 'package:gitjournal/settings.dart'; import 'package:gitjournal/settings.dart';
import 'package:gitjournal/widgets/folder_selection_dialog.dart'; import 'package:gitjournal/widgets/folder_selection_dialog.dart';
@ -74,7 +75,7 @@ class SettingsImagesScreenState extends State<SettingsImagesScreen> {
}, },
), ),
), ),
body: ProOverlay(child: body), body: ProOverlay(feature: Feature.imageSupport, child: body),
); );
} }
} }

View File

@ -9,6 +9,7 @@ import 'package:gitjournal/core/note.dart';
import 'package:gitjournal/core/note_serializer.dart'; import 'package:gitjournal/core/note_serializer.dart';
import 'package:gitjournal/editors/note_body_editor.dart'; import 'package:gitjournal/editors/note_body_editor.dart';
import 'package:gitjournal/editors/note_title_editor.dart'; import 'package:gitjournal/editors/note_title_editor.dart';
import 'package:gitjournal/features.dart';
import 'package:gitjournal/screens/settings_widgets.dart'; import 'package:gitjournal/screens/settings_widgets.dart';
import 'package:gitjournal/settings.dart'; import 'package:gitjournal/settings.dart';
import 'package:gitjournal/widgets/pro_overlay.dart'; import 'package:gitjournal/widgets/pro_overlay.dart';
@ -65,6 +66,7 @@ class _NoteMetadataSettingsScreenState
}, },
), ),
ProOverlay( ProOverlay(
feature: Feature.yamlModifiedKey,
child: ListPreference( child: ListPreference(
title: tr("settings.noteMetaData.modified"), title: tr("settings.noteMetaData.modified"),
options: [ options: [
@ -84,6 +86,7 @@ class _NoteMetadataSettingsScreenState
), ),
), ),
ProOverlay( ProOverlay(
feature: Feature.yamlCreatedKey,
child: ListPreference( child: ListPreference(
title: tr("settings.noteMetaData.created"), title: tr("settings.noteMetaData.created"),
options: [ options: [
@ -101,6 +104,7 @@ class _NoteMetadataSettingsScreenState
), ),
), ),
ProOverlay( ProOverlay(
feature: Feature.yamlTagsKey,
child: ListPreference( child: ListPreference(
title: tr("settings.noteMetaData.tags"), title: tr("settings.noteMetaData.tags"),
options: [ options: [
@ -118,6 +122,7 @@ class _NoteMetadataSettingsScreenState
), ),
), ),
ProOverlay( ProOverlay(
feature: Feature.metaDataTitle,
child: ListPreference( child: ListPreference(
title: tr("settings.noteMetaData.titleMetaData.title"), title: tr("settings.noteMetaData.titleMetaData.title"),
options: [ options: [

View File

@ -6,6 +6,7 @@ import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:gitjournal/core/notes_folder_fs.dart'; import 'package:gitjournal/core/notes_folder_fs.dart';
import 'package:gitjournal/features.dart';
import 'package:gitjournal/screens/debug_screen.dart'; import 'package:gitjournal/screens/debug_screen.dart';
import 'package:gitjournal/screens/settings_editors.dart'; import 'package:gitjournal/screens/settings_editors.dart';
import 'package:gitjournal/screens/settings_experimental.dart'; import 'package:gitjournal/screens/settings_experimental.dart';
@ -157,6 +158,7 @@ class SettingsListState extends State<SettingsList> {
}, },
), ),
ProOverlay( ProOverlay(
feature: Feature.customizeHomeScreen,
child: ListPreference( child: ListPreference(
title: tr('settings.display.homeScreen'), title: tr('settings.display.homeScreen'),
currentOption: settings.homeScreen.toPublicString(), currentOption: settings.homeScreen.toPublicString(),

View File

@ -10,6 +10,7 @@ import 'package:gitjournal/core/flattened_notes_folder.dart';
import 'package:gitjournal/core/note.dart'; import 'package:gitjournal/core/note.dart';
import 'package:gitjournal/core/note_serializer.dart'; import 'package:gitjournal/core/note_serializer.dart';
import 'package:gitjournal/core/notes_folder_fs.dart'; import 'package:gitjournal/core/notes_folder_fs.dart';
import 'package:gitjournal/features.dart';
import 'package:gitjournal/screens/folder_view.dart'; import 'package:gitjournal/screens/folder_view.dart';
import 'package:gitjournal/widgets/app_bar_menu_button.dart'; import 'package:gitjournal/widgets/app_bar_menu_button.dart';
import 'package:gitjournal/widgets/app_drawer.dart'; import 'package:gitjournal/widgets/app_drawer.dart';
@ -33,7 +34,12 @@ class TagListingScreen extends StatelessWidget {
title: Text(tr('screens.tags.title')), title: Text(tr('screens.tags.title')),
leading: GJAppBarMenuButton(), leading: GJAppBarMenuButton(),
), ),
body: Scrollbar(child: ProOverlay(child: listView)), body: Scrollbar(
child: ProOverlay(
feature: Feature.tags,
child: listView,
),
),
drawer: AppDrawer(), drawer: AppDrawer(),
); );
} }

View File

@ -7,6 +7,7 @@ import 'package:path/path.dart' as p;
import 'package:gitjournal/core/link.dart'; import 'package:gitjournal/core/link.dart';
import 'package:gitjournal/core/note.dart'; import 'package:gitjournal/core/note.dart';
import 'package:gitjournal/core/notes_folder_fs.dart'; import 'package:gitjournal/core/notes_folder_fs.dart';
import 'package:gitjournal/features.dart';
import 'package:gitjournal/folder_views/common.dart'; import 'package:gitjournal/folder_views/common.dart';
import 'package:gitjournal/utils/logger.dart'; import 'package:gitjournal/utils/logger.dart';
import 'package:gitjournal/widgets/pro_overlay.dart'; import 'package:gitjournal/widgets/pro_overlay.dart';
@ -108,7 +109,7 @@ class _NoteBacklinkRendererState extends State<NoteBacklinkRenderer> {
child: c, child: c,
), ),
); );
return ProOverlay(child: child); return ProOverlay(feature: Feature.backlinks, child: child);
} }
} }

View File

@ -3,12 +3,15 @@ import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:gitjournal/analytics.dart';
import 'package:gitjournal/features.dart';
import 'package:gitjournal/settings.dart'; import 'package:gitjournal/settings.dart';
class ProOverlay extends StatelessWidget { class ProOverlay extends StatelessWidget {
final Widget child; final Widget child;
final Feature feature;
ProOverlay({@required this.child}); ProOverlay({@required this.child, @required this.feature});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -27,6 +30,11 @@ class ProOverlay extends StatelessWidget {
), ),
onTap: () { onTap: () {
Navigator.pushNamed(context, "/purchase"); Navigator.pushNamed(context, "/purchase");
logEvent(
Event.PurchaseScreenOpen,
parameters: {"from": feature.featureName},
);
}, },
); );
} }