├── iOS ├── 📥NotesImport │ ├── 📥InputMode.swift │ ├── 📥NotesImportSheetButton.swift │ ├── 📥FileImportSection.swift │ ├── 📥NotesImportSheetView.swift │ └── 📥TextImportSection.swift ├── 📗NoteView │ ├── 📗Placement.swift │ └── FocusedValues(extension).swift ├── Supporting files │ ├── 🌐Localization │ │ ├── ja.lproj │ │ │ └── InfoPlist.strings │ │ ├── en.lproj │ │ │ └── InfoPlist.strings │ │ └── 🌐AppStoreDescription.xcstrings │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── AD │ │ │ ├── Contents.json │ │ │ ├── ADPreview.imageset │ │ │ │ ├── ADPreview(大).heic │ │ │ │ └── Contents.json │ │ │ ├── icon │ │ │ │ ├── TapWeight.imageset │ │ │ │ │ ├── TapWeight.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── LockInNote.imageset │ │ │ │ │ ├── LockInNote.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── FadeInAlarm.imageset │ │ │ │ │ ├── FadeInAlarm.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── FlipByBlink.imageset │ │ │ │ │ ├── FlipByBlink.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── PlainShogiBoard.imageset │ │ │ │ │ ├── Plain将棋盤.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── MemorizeWidget.imageset │ │ │ │ │ ├── MemorizeWidget.heic │ │ │ │ │ └── Contents.json │ │ │ │ └── TapTemperature.imageset │ │ │ │ │ ├── TapTemperature.heic │ │ │ │ │ └── Contents.json │ │ │ ├── mock │ │ │ │ ├── FadeInAlarm.imageset │ │ │ │ │ ├── fia(大).heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── FlipByBlink.imageset │ │ │ │ │ ├── fbb(大).heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── MemorizeWidget.imageset │ │ │ │ │ ├── mw(大).heic │ │ │ │ │ ├── mw(大) 1.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── LockInNote.imageset │ │ │ │ │ ├── top1200w(大).heic │ │ │ │ │ ├── topLIN1200w(大).heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── PlainShogiBoard.imageset │ │ │ │ │ ├── ps_v1.3.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── TapWeight.imageset │ │ │ │ │ ├── TWtop1200wEN.heic │ │ │ │ │ ├── TWtop1200wJA.heic │ │ │ │ │ └── Contents.json │ │ │ │ └── TapTemperature.imageset │ │ │ │ │ ├── TTtop1200wEN.heic │ │ │ │ │ ├── TTtop1200wJA.heic │ │ │ │ │ └── Contents.json │ │ │ ├── apple_health_badge.imageset │ │ │ │ └── Contents.json │ │ │ └── appstore_badge.imageset │ │ │ │ └── Contents.json │ │ ├── Image │ │ │ ├── Contents.json │ │ │ ├── moveBySwiping.imageset │ │ │ │ ├── Group 14(中).heic │ │ │ │ └── Contents.json │ │ │ ├── sample_numbers.imageset │ │ │ │ ├── IMG_3911 小.heic │ │ │ │ └── Contents.json │ │ │ ├── sample_appleNotes.imageset │ │ │ │ ├── IMG_3912 小.heic │ │ │ │ └── Contents.json │ │ │ ├── sample_importedNotes.imageset │ │ │ │ ├── IMG_3913 小.heic │ │ │ │ └── Contents.json │ │ │ ├── deleteBySwiping.imageset │ │ │ │ ├── swipeLeft Group 13(中).heic │ │ │ │ └── Contents.json │ │ │ ├── systemFamilyExample.imageset │ │ │ │ ├── HomeScreenExample.heic │ │ │ │ └── Contents.json │ │ │ ├── accessoryFamilyExample.imageset │ │ │ │ ├── LockScreenExample.heic │ │ │ │ └── Contents.json │ │ │ ├── shareSheetFile.imageset │ │ │ │ ├── fileShareSheet Group 9(中).heic │ │ │ │ └── Contents.json │ │ │ ├── systemFamilyDefault.imageset │ │ │ │ ├── systemFamilyDefault.heic │ │ │ │ └── Contents.json │ │ │ ├── AccessoryFamilyDefault.imageset │ │ │ │ ├── AccessoryFamilyDefault.heic │ │ │ │ └── Contents.json │ │ │ ├── numbers_csv_tsv_export.imageset │ │ │ │ ├── numbers_csv_tsv_export.heic │ │ │ │ └── Contents.json │ │ │ ├── systemFamilyMultiNotes.imageset │ │ │ │ ├── systemFamilyMultiNotes.heic │ │ │ │ └── Contents.json │ │ │ ├── shareSheetText.imageset │ │ │ │ ├── selectedTextShareSheet Group 8(中).heic │ │ │ │ └── Contents.json │ │ │ ├── systemFamilyShowComment.imageset │ │ │ │ ├── systemFamilyShowComment.heic │ │ │ │ └── Contents.json │ │ │ ├── AccessoryFamilyMultiNotes.imageset │ │ │ │ ├── AccessoryFamilyMultiNotes.heic │ │ │ │ └── Contents.json │ │ │ ├── AccessoryFamilyShowComment.imageset │ │ │ │ ├── AccessoryFamilyShowComment.heic │ │ │ │ └── Contents.json │ │ │ ├── importNotesButton.imageset │ │ │ │ ├── importNotesInApp trim edit Group 12.heic │ │ │ │ └── Contents.json │ │ │ └── sample_txt_macTextEdit.imageset │ │ │ │ ├── スクリーンショット 2022-10-05 20.53.09 小.heic │ │ │ │ └── Contents.json │ │ ├── Others │ │ │ ├── Contents.json │ │ │ └── Developer_Publisher.imageset │ │ │ │ ├── Developer_Publisher.heic │ │ │ │ └── Contents.json │ │ ├── RoundedIcon.imageset │ │ │ ├── icon.png │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── AppIcon1024.png │ │ │ └── Contents.json │ │ └── AccentColor.colorset │ │ │ └── Contents.json │ ├── Info.plist │ └── iOS.entitlements ├── App Extensions │ ├── Widget │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── AppIcon1024.png │ │ │ │ └── Contents.json │ │ │ ├── AccentColor.colorset │ │ │ │ └── Contents.json │ │ │ └── WidgetBackground.colorset │ │ │ │ └── Contents.json │ │ ├── WidgetBundle.swift │ │ ├── Info.plist │ │ └── Widget.entitlements │ └── ShareExtension │ │ ├── 📨InputType.swift │ │ ├── 📨HostingViewController.swift │ │ ├── Info.plist │ │ ├── ShareExtension.entitlements │ │ └── Base.lproj │ │ └── MainInterface.storyboard ├── 📚NotesListTab │ ├── 📚DisableInEditMode.swift │ └── 📚NotesMenuButton.swift ├── 🔖Tab&Sidebar │ ├── 🔖TabView.swift │ ├── 🔖Sidebar.swift │ ├── 🔖Tab.swift │ └── 🔖SplitView.swift ├── App.swift ├── Rest │ ├── 📣ADContentView.swift │ ├── 💬RequestUserReview.swift │ ├── 🚮DeleteNoteButton.swift │ ├── 🆕NewNoteCommand.swift │ ├── ℹ️AboutAppTab.swift │ ├── 📘DictionarySheetView.swift │ └── 🩹Workaround.swift ├── 📖WidgetSheet │ ├── 📖DismissWidgetSheetOnBackground.swift │ ├── 📖DeletedNoteView.swift │ ├── 📖DictionaryButton.swift │ ├── 📖WidgetSheetView.swift │ ├── 📖MoveEndButton.swift │ ├── 📖SearchButton.swift │ └── 📖SingleNoteLayoutView.swift ├── ContentView.swift ├── 📰Sheet │ ├── 📰DismissButton.swift │ ├── 📰SheetOnWidgetSheet.swift │ └── 📰SheetHandlerOnContentView.swift ├── 🔍Search │ └── 🔍SearchSheetView.swift ├── 🎛️Option │ ├── 🎛️BeforeAfterImages.swift │ ├── 🎛️CommentOnWidgetOption.swift │ └── 🎛️MultiNotesOnWidgetOption.swift └── 📱AppModel(extension).swift ├── Shared ├── 🪧Widget │ ├── 🪧Kind.swift │ ├── 🪧Phase.swift │ ├── 🪧Entry.swift │ ├── Rest │ │ ├── 🪧ContainerBackground.swift │ │ ├── 🪧PlaceholderView.swift │ │ └── 🪧NoNoteView.swift │ ├── 🪧SubWidget.swift │ ├── 🪧Tag.swift │ ├── 🪧PrimaryWidget.swift │ └── 🪧EntryView.swift ├── Supporting files │ ├── README assets │ │ └── 1200w.png │ ├── Archive │ │ └── memo.md │ └── 🌐Localization │ │ └── 🌐ADAppName.xcstrings ├── 💾Data │ ├── UserDefaults(extension).swift │ ├── 🩹WorkaroundOnIOS15.swift │ ├── 💾ICloud.swift │ └── 💾UserDefaults.swift ├── 🗑Trash │ ├── 🗑DeletedContent.swift │ ├── 🗑TrashModel.swift │ └── 🗑TrashViewComponent.swift ├── 📥NotesImport │ ├── 📥Error.swift │ └── 📥SeparatorPicker.swift ├── 📗Note&Notes │ ├── 📗Note.swift │ ├── 📚Notes.swift │ └── 📚TextConvert.swift ├── 🔍Search │ ├── 🔍FailureAlert.swift │ └── 🔍SearchModel.swift ├── Rest │ ├── 📰SheetOnContentView.swift │ ├── 💁GuideViewComponent.swift │ ├── 💥Feedback.swift │ ├── 📣ADModel.swift │ └── 🚮DeleteAllNotesButton.swift └── 🎛️Option │ ├── 🎛️Key.swift │ ├── 🎛️Option.swift │ ├── 🎛️Default.swift │ ├── 🎛️MultilineTextAlignment.swift │ └── 🎛️RandomModeToggle.swift ├── watchOS ├── Supporting files │ ├── ja.lproj │ │ └── InfoPlist.strings │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── iconImage.imageset │ │ │ ├── icon.png │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── AppIcon1024 1.png │ │ │ └── Contents.json │ │ └── AccentColor.colorset │ │ │ └── Contents.json │ └── watchOS.entitlements ├── App Extensions │ └── Widget │ │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── AppIcon1024.png │ │ │ └── Contents.json │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ └── WidgetBackground.colorset │ │ │ └── Contents.json │ │ ├── WidgetBundle.swift │ │ ├── Info.plist │ │ └── Widget.entitlements ├── App.swift ├── 📱AppModel(extension).swift ├── 📰SheetHandlerOnContentView.swift ├── Rest │ ├── 💁GuideMenu.swift │ └── 🆕NewNoteShortcut.swift ├── ContentView.swift └── 📚NotesListMenu.swift ├── macOS ├── Supporting files │ ├── Assets.xcassets │ │ ├── AD │ │ │ ├── Contents.json │ │ │ ├── ADPreview.imageset │ │ │ │ ├── ADPreviewMid.png │ │ │ │ └── Contents.json │ │ │ ├── icon │ │ │ │ ├── TapWeight.imageset │ │ │ │ │ ├── TapWeight.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── LockInNote.imageset │ │ │ │ │ ├── LockInNote.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── FadeInAlarm.imageset │ │ │ │ │ ├── FadeInAlarm.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── FlipByBlink.imageset │ │ │ │ │ ├── FlipByBlink.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── PlainShogiBoard.imageset │ │ │ │ │ ├── Plain将棋盤.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── MemorizeWidget.imageset │ │ │ │ │ ├── MemorizeWidget.heic │ │ │ │ │ └── Contents.json │ │ │ │ └── TapTemperature.imageset │ │ │ │ │ ├── TapTemperature.heic │ │ │ │ │ └── Contents.json │ │ │ ├── mock │ │ │ │ ├── FadeInAlarm.imageset │ │ │ │ │ ├── fia(大).heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── FlipByBlink.imageset │ │ │ │ │ ├── fbb(大).heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── LockInNote.imageset │ │ │ │ │ ├── top1200w(大).heic │ │ │ │ │ ├── topLIN1200w(大).heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── MemorizeWidget.imageset │ │ │ │ │ ├── mw(大) 1.heic │ │ │ │ │ ├── mw(大).heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── TapWeight.imageset │ │ │ │ │ ├── TWtop1200wEN.heic │ │ │ │ │ ├── TWtop1200wJA.heic │ │ │ │ │ └── Contents.json │ │ │ │ ├── PlainShogiBoard.imageset │ │ │ │ │ ├── ps_v1.3.heic │ │ │ │ │ └── Contents.json │ │ │ │ └── TapTemperature.imageset │ │ │ │ │ ├── TTtop1200wEN.heic │ │ │ │ │ ├── TTtop1200wJA.heic │ │ │ │ │ └── Contents.json │ │ │ ├── apple_health_badge.imageset │ │ │ │ └── Contents.json │ │ │ └── appstore_badge.imageset │ │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Others │ │ │ ├── Contents.json │ │ │ └── Developer_Publisher.imageset │ │ │ │ ├── Developer_Publisher.heic │ │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── macOS128.png │ │ │ ├── macOS16.png │ │ │ ├── macOS256.png │ │ │ ├── macOS32.png │ │ │ ├── macOS512.png │ │ │ ├── macOS64.png │ │ │ ├── macOS1024.png │ │ │ ├── macOS256 1.png │ │ │ ├── macOS32 1.png │ │ │ ├── macOS512 1.png │ │ │ └── Contents.json │ │ └── AccentColor.colorset │ │ │ └── Contents.json │ ├── Info.plist │ ├── macOS.entitlements │ └── 🌐Localization │ │ ├── InfoPlist.xcstrings │ │ └── 🌐AppStoreDescription.xcstrings ├── App Extensions │ └── Widget │ │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── macOS128.png │ │ │ ├── macOS16.png │ │ │ ├── macOS256.png │ │ │ ├── macOS32.png │ │ │ ├── macOS512.png │ │ │ ├── macOS64.png │ │ │ ├── macOS1024.png │ │ │ ├── macOS256 1.png │ │ │ ├── macOS32 1.png │ │ │ ├── macOS512 1.png │ │ │ └── Contents.json │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ └── WidgetBackground.colorset │ │ │ └── Contents.json │ │ ├── WidgetBundle.swift │ │ ├── Info.plist │ │ ├── Widget.entitlements │ │ └── InfoPlist.xcstrings ├── 📥NotesImport │ ├── 📥NotSupportMultiLineTextInNoteSection.swift │ ├── 📥DismissButton.swift │ ├── 📥NotesImportFileSheetView.swift │ └── 📥ConvertedNotesMenu.swift ├── 📚NotesWindow │ ├── 🔝NewNoteOnTopButton.swift │ ├── 📚ContentView.swift │ ├── 📚NotesWindow.swift │ ├── 🔦FocusedModel │ │ ├── 🔦FocusedModelHandler.swift │ │ └── FocusedValues(extension).swift │ ├── 🛫MoveTopButton.swift │ ├── 🛬MoveEndButton.swift │ ├── 👆InsertAboveButton.swift │ ├── 👇InsertBelowButton.swift │ ├── 🚏ContextMenu.swift │ ├── 🔍SearchButton.swift │ ├── 📘DictionaryButton.swift │ └── 📰SheetHandlerOnContentView.swift ├── App.swift ├── Rest │ ├── Rest │ │ ├── 🛒InAppPurchaseCommand.swift │ │ ├── 🛒InAppPurchaseWindow.swift │ │ └── ℹ️HelpCommands.swift │ ├── 💬RequestUserReview.swift │ ├── 📣ADSheet.swift │ └── 📤NotesExportSheetView.swift ├── 🔧Settings │ ├── 🔧MenuBarPanel.swift │ ├── 🔧Settings.swift │ ├── 🔧WidgetPanel.swift │ └── 🔧GuidePanel.swift ├── 📱AppModel(NSApplicationDelegate).swift ├── 🏗️MenuBarShortcut │ └── 🏗️MenuBarShortcut.swift ├── 🗑TrashWindow │ └── 🗑TrashWindow.swift ├── 📖WidgetSheet │ ├── 📖MoveEndButton.swift │ ├── 📖WidgetSheetView.swift │ └── 📖SheetDebug.swift └── 📱AppModel(extension).swift └── MemorizeWidget.xcodeproj ├── project.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist └── xcuserdata ├── account2309.xcuserdatad └── xcschemes │ └── xcschememanagement.plist └── meisei.xcuserdatad └── xcschemes └── xcschememanagement.plist /iOS/📥NotesImport/📥InputMode.swift: -------------------------------------------------------------------------------- 1 | enum 📥InputMode: String { 2 | case file 3 | case text 4 | } 5 | -------------------------------------------------------------------------------- /iOS/📗NoteView/📗Placement.swift: -------------------------------------------------------------------------------- 1 | enum 📗Placement { 2 | case notesList 3 | case widgetSheet 4 | } 5 | -------------------------------------------------------------------------------- /Shared/🪧Widget/🪧Kind.swift: -------------------------------------------------------------------------------- 1 | enum 🪧Kind { 2 | case primary 3 | case sub 4 | case newNoteShortcut 5 | } 6 | -------------------------------------------------------------------------------- /watchOS/Supporting files/ja.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | CFBundleDisplayName = "暗記ウィジェット"; 2 | CFBundleName = "暗記ウィジェット"; 3 | -------------------------------------------------------------------------------- /Shared/🪧Widget/🪧Phase.swift: -------------------------------------------------------------------------------- 1 | enum 🪧Phase { 2 | case placeholder 3 | case snapshot 4 | case inTimeline 5 | } 6 | -------------------------------------------------------------------------------- /iOS/Supporting files/🌐Localization/ja.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | CFBundleDisplayName = "暗記Widget"; 2 | CFBundleName = "暗記ウィジェット"; 3 | -------------------------------------------------------------------------------- /watchOS/Supporting files/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | CFBundleDisplayName = "MemorizeWidget"; 2 | CFBundleName = "MemorizeWidget"; 3 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /iOS/Supporting files/🌐Localization/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | CFBundleDisplayName = "MemorizeW"; 2 | CFBundleName = "MemorizeWidget"; 3 | -------------------------------------------------------------------------------- /iOS/App Extensions/Widget/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /watchOS/Supporting files/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Others/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/Others/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /watchOS/App Extensions/Widget/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Shared/Supporting files/README assets/1200w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/Shared/Supporting files/README assets/1200w.png -------------------------------------------------------------------------------- /Shared/💾Data/UserDefaults(extension).swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension UserDefaults { 4 | static var ⓐppGroup: UserDefaults { 💾UserDefaults.appGroup } 5 | } 6 | -------------------------------------------------------------------------------- /iOS/App Extensions/ShareExtension/📨InputType.swift: -------------------------------------------------------------------------------- 1 | enum 📨InputType { 2 | case textFile 3 | case selectedText 4 | case improperFile 5 | case exceedDataLimitation 6 | } 7 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/RoundedIcon.imageset/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/RoundedIcon.imageset/icon.png -------------------------------------------------------------------------------- /watchOS/Supporting files/Assets.xcassets/iconImage.imageset/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/watchOS/Supporting files/Assets.xcassets/iconImage.imageset/icon.png -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS128.png -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS16.png -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS256.png -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS32.png -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS512.png -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS64.png -------------------------------------------------------------------------------- /Shared/🪧Widget/🪧Entry.swift: -------------------------------------------------------------------------------- 1 | import WidgetKit 2 | 3 | struct 🪧Entry: TimelineEntry { 4 | let date: Date 5 | var kind: 🪧Kind 6 | var phase: 🪧Phase 7 | var pickedNotes: 📚Notes 8 | } 9 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AppIcon.appiconset/AppIcon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AppIcon.appiconset/AppIcon1024.png -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS1024.png -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS256 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS256 1.png -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS32 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS32 1.png -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS512 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/macOS512 1.png -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS128.png -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS16.png -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS256.png -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS32.png -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS512.png -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS64.png -------------------------------------------------------------------------------- /iOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/AppIcon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/AppIcon1024.png -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/ADPreview.imageset/ADPreview(大).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/ADPreview.imageset/ADPreview(大).heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/TapWeight.imageset/TapWeight.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/icon/TapWeight.imageset/TapWeight.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/FadeInAlarm.imageset/fia(大).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/mock/FadeInAlarm.imageset/fia(大).heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/FlipByBlink.imageset/fbb(大).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/mock/FlipByBlink.imageset/fbb(大).heic -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS1024.png -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS256 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS256 1.png -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS32 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS32 1.png -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS512 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/macOS512 1.png -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/ADPreview.imageset/ADPreviewMid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/ADPreview.imageset/ADPreviewMid.png -------------------------------------------------------------------------------- /watchOS/Supporting files/Assets.xcassets/AppIcon.appiconset/AppIcon1024 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/watchOS/Supporting files/Assets.xcassets/AppIcon.appiconset/AppIcon1024 1.png -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "properties" : { 7 | "provides-namespace" : true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/LockInNote.imageset/LockInNote.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/icon/LockInNote.imageset/LockInNote.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "properties" : { 7 | "provides-namespace" : true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/MemorizeWidget.imageset/mw(大).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/mock/MemorizeWidget.imageset/mw(大).heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/TapWeight.imageset/TapWeight.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/icon/TapWeight.imageset/TapWeight.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/FadeInAlarm.imageset/fia(大).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/mock/FadeInAlarm.imageset/fia(大).heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/FlipByBlink.imageset/fbb(大).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/mock/FlipByBlink.imageset/fbb(大).heic -------------------------------------------------------------------------------- /watchOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/AppIcon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/watchOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/AppIcon1024.png -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/FadeInAlarm.imageset/FadeInAlarm.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/icon/FadeInAlarm.imageset/FadeInAlarm.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/FlipByBlink.imageset/FlipByBlink.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/icon/FlipByBlink.imageset/FlipByBlink.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/PlainShogiBoard.imageset/Plain将棋盤.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/icon/PlainShogiBoard.imageset/Plain将棋盤.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/LockInNote.imageset/top1200w(大).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/mock/LockInNote.imageset/top1200w(大).heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/MemorizeWidget.imageset/mw(大) 1.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/mock/MemorizeWidget.imageset/mw(大) 1.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/PlainShogiBoard.imageset/ps_v1.3.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/mock/PlainShogiBoard.imageset/ps_v1.3.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/TapWeight.imageset/TWtop1200wEN.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/mock/TapWeight.imageset/TWtop1200wEN.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/TapWeight.imageset/TWtop1200wJA.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/mock/TapWeight.imageset/TWtop1200wJA.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/moveBySwiping.imageset/Group 14(中).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/moveBySwiping.imageset/Group 14(中).heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/sample_numbers.imageset/IMG_3911 小.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/sample_numbers.imageset/IMG_3911 小.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "properties" : { 7 | "provides-namespace" : true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/LockInNote.imageset/LockInNote.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/icon/LockInNote.imageset/LockInNote.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "properties" : { 7 | "provides-namespace" : true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/LockInNote.imageset/top1200w(大).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/mock/LockInNote.imageset/top1200w(大).heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/MemorizeWidget.imageset/mw(大) 1.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/mock/MemorizeWidget.imageset/mw(大) 1.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/MemorizeWidget.imageset/mw(大).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/mock/MemorizeWidget.imageset/mw(大).heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/TapWeight.imageset/TWtop1200wEN.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/mock/TapWeight.imageset/TWtop1200wEN.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/TapWeight.imageset/TWtop1200wJA.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/mock/TapWeight.imageset/TWtop1200wJA.heic -------------------------------------------------------------------------------- /MemorizeWidget.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/LockInNote.imageset/topLIN1200w(大).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/mock/LockInNote.imageset/topLIN1200w(大).heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/sample_appleNotes.imageset/IMG_3912 小.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/sample_appleNotes.imageset/IMG_3912 小.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/FadeInAlarm.imageset/FadeInAlarm.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/icon/FadeInAlarm.imageset/FadeInAlarm.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/FlipByBlink.imageset/FlipByBlink.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/icon/FlipByBlink.imageset/FlipByBlink.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/PlainShogiBoard.imageset/Plain将棋盤.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/icon/PlainShogiBoard.imageset/Plain将棋盤.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/PlainShogiBoard.imageset/ps_v1.3.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/mock/PlainShogiBoard.imageset/ps_v1.3.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/MemorizeWidget.imageset/MemorizeWidget.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/icon/MemorizeWidget.imageset/MemorizeWidget.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/TapTemperature.imageset/TapTemperature.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/icon/TapTemperature.imageset/TapTemperature.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/TapTemperature.imageset/TTtop1200wEN.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/mock/TapTemperature.imageset/TTtop1200wEN.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/TapTemperature.imageset/TTtop1200wJA.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/AD/mock/TapTemperature.imageset/TTtop1200wJA.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/sample_importedNotes.imageset/IMG_3913 小.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/sample_importedNotes.imageset/IMG_3913 小.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/LockInNote.imageset/topLIN1200w(大).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/mock/LockInNote.imageset/topLIN1200w(大).heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/TapTemperature.imageset/TTtop1200wEN.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/mock/TapTemperature.imageset/TTtop1200wEN.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/TapTemperature.imageset/TTtop1200wJA.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/mock/TapTemperature.imageset/TTtop1200wJA.heic -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/WidgetBundle.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct MacOSWidgetBundle: WidgetBundle { 5 | var body: some Widget { 6 | 🪧PrimaryWidget() 7 | 🪧SubWidget() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/MemorizeWidget.imageset/MemorizeWidget.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/icon/MemorizeWidget.imageset/MemorizeWidget.heic -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/TapTemperature.imageset/TapTemperature.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/AD/icon/TapTemperature.imageset/TapTemperature.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/deleteBySwiping.imageset/swipeLeft Group 13(中).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/deleteBySwiping.imageset/swipeLeft Group 13(中).heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/systemFamilyExample.imageset/HomeScreenExample.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/systemFamilyExample.imageset/HomeScreenExample.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/accessoryFamilyExample.imageset/LockScreenExample.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/accessoryFamilyExample.imageset/LockScreenExample.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/shareSheetFile.imageset/fileShareSheet Group 9(中).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/shareSheetFile.imageset/fileShareSheet Group 9(中).heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/systemFamilyDefault.imageset/systemFamilyDefault.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/systemFamilyDefault.imageset/systemFamilyDefault.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Others/Developer_Publisher.imageset/Developer_Publisher.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Others/Developer_Publisher.imageset/Developer_Publisher.heic -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/WidgetBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/Others/Developer_Publisher.imageset/Developer_Publisher.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/macOS/Supporting files/Assets.xcassets/Others/Developer_Publisher.imageset/Developer_Publisher.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/AccessoryFamilyDefault.imageset/AccessoryFamilyDefault.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/AccessoryFamilyDefault.imageset/AccessoryFamilyDefault.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/numbers_csv_tsv_export.imageset/numbers_csv_tsv_export.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/numbers_csv_tsv_export.imageset/numbers_csv_tsv_export.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/systemFamilyMultiNotes.imageset/systemFamilyMultiNotes.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/systemFamilyMultiNotes.imageset/systemFamilyMultiNotes.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/shareSheetText.imageset/selectedTextShareSheet Group 8(中).heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/shareSheetText.imageset/selectedTextShareSheet Group 8(中).heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/systemFamilyShowComment.imageset/systemFamilyShowComment.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/systemFamilyShowComment.imageset/systemFamilyShowComment.heic -------------------------------------------------------------------------------- /iOS/App Extensions/Widget/WidgetBundle.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct IOSWidgetBundle: WidgetBundle { 5 | var body: some Widget { 6 | 🪧PrimaryWidget() 7 | 🪧NewNoteShortcutWidget() 8 | 🪧SubWidget() 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/AccessoryFamilyMultiNotes.imageset/AccessoryFamilyMultiNotes.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/AccessoryFamilyMultiNotes.imageset/AccessoryFamilyMultiNotes.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/AccessoryFamilyShowComment.imageset/AccessoryFamilyShowComment.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/AccessoryFamilyShowComment.imageset/AccessoryFamilyShowComment.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/importNotesButton.imageset/importNotesInApp trim edit Group 12.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/importNotesButton.imageset/importNotesInApp trim edit Group 12.heic -------------------------------------------------------------------------------- /watchOS/App Extensions/Widget/WidgetBundle.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct WatchOSWidgetBundle: WidgetBundle { 5 | var body: some Widget { 6 | 🪧PrimaryWidget() 7 | 🪧NewNoteShortcutWidget() 8 | 🪧SubWidget() 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Shared/🗑Trash/🗑DeletedContent.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct 🗑DeletedContent: Codable, Equatable, Identifiable { 4 | var date: Date 5 | var notes: 📚Notes 6 | var id: Date { self.date } 7 | } 8 | 9 | typealias 🗑DeletedContents = [🗑DeletedContent] 10 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/sample_txt_macTextEdit.imageset/スクリーンショット 2022-10-05 20.53.09 小.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlipByBlink/MemorizeWidget/HEAD/iOS/Supporting files/Assets.xcassets/Image/sample_txt_macTextEdit.imageset/スクリーンショット 2022-10-05 20.53.09 小.heic -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/RoundedIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icon.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /watchOS/Supporting files/Assets.xcassets/iconImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icon.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/ADPreview.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ADPreview(大).heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/TapWeight.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "TapWeight.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/FadeInAlarm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "fia(大).heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/FlipByBlink.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "fbb(大).heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/ADPreview.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ADPreviewMid.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/FadeInAlarm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "FadeInAlarm.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/FlipByBlink.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "FlipByBlink.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/LockInNote.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "LockInNote.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/PlainShogiBoard.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Plain将棋盤.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/PlainShogiBoard.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ps_v1.3.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/sample_numbers.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "IMG_3911 小.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/LockInNote.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "LockInNote.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/TapWeight.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "TapWeight.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/FadeInAlarm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "fia(大).heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/FlipByBlink.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "fbb(大).heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/MemorizeWidget.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "MemorizeWidget.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/icon/TapTemperature.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "TapTemperature.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/sample_appleNotes.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "IMG_3912 小.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/sample_importedNotes.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "IMG_3913 小.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/FadeInAlarm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "FadeInAlarm.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/FlipByBlink.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "FlipByBlink.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/PlainShogiBoard.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Plain将棋盤.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/PlainShogiBoard.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ps_v1.3.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/MemorizeWidget.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "MemorizeWidget.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/icon/TapTemperature.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "TapTemperature.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Others/Developer_Publisher.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Developer_Publisher.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /watchOS/App.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct WatchOSApp: App { 5 | @StateObject private var model = 📱AppModel() 6 | var body: some Scene { 7 | WindowGroup { 8 | ContentView() 9 | .environmentObject(self.model) 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/numbers_csv_tsv_export.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "numbers_csv_tsv_export.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/Others/Developer_Publisher.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Developer_Publisher.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/📚NotesListTab/📚DisableInEditMode.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📚DisableInEditMode: ViewModifier { 4 | @Environment(\.editMode) var editMode 5 | func body(content: Content) -> some View { 6 | content 7 | .disabled(self.editMode?.wrappedValue == .active) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/sample_txt_macTextEdit.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "スクリーンショット 2022-10-05 20.53.09 小.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MemorizeWidget.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macOS/📥NotesImport/📥NotSupportMultiLineTextInNoteSection.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📥NotSupportMultiLineTextInNoteSection: View { 4 | var body: some View { 5 | Section { 6 | Text("Not support multi line text in note.") 7 | .foregroundStyle(.secondary) 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "AppIcon1024.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /iOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "AppIcon1024.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /iOS/🔖Tab&Sidebar/🔖TabView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🔖TabView: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | var body: some View { 6 | TabView(selection: self.$model.selectedTab) { 7 | ForEach(🔖Tab.allCases) { 8 | $0.detailView() 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/📗NoteView/FocusedValues(extension).swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension FocusedValues { 4 | var editingNote: Self.EditingNoteKey.Value? { 5 | get { self[Self.EditingNoteKey.self] } 6 | set { self[Self.EditingNoteKey.self] = newValue } 7 | } 8 | struct EditingNoteKey: FocusedValueKey { typealias Value = 📗Note } 9 | } 10 | -------------------------------------------------------------------------------- /watchOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "AppIcon1024.png", 5 | "idiom" : "universal", 6 | "platform" : "watchos", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /watchOS/Supporting files/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "AppIcon1024 1.png", 5 | "idiom" : "universal", 6 | "platform" : "watchos", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /macOS/Supporting files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ITSAppUsesNonExemptEncryption 6 | 7 | LSHasLocalizedDisplayName 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/🔝NewNoteOnTopButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🔝NewNoteOnTopButton: View { 4 | @FocusedObject var model: 📱AppModel? 5 | var body: some View { 6 | Button { 7 | self.model?.addNewNoteOnTop() 8 | } label: { 9 | Label("New note on top", systemImage: "plus") 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/App.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct IOSApp: App { 5 | @StateObject private var model = 📱AppModel() 6 | var body: some Scene { 7 | WindowGroup { 8 | ContentView() 9 | .environmentObject(self.model) 10 | } 11 | .commands { 12 | 🆕NewNoteCommand(self.model) 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /iOS/Rest/📣ADContentView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📣ADContentView: View { 4 | @EnvironmentObject var model: 🛒InAppPurchaseModel 5 | @State private var targetApp: 📣ADTargetApp = .pickUpAppWithout(.MemorizeWidget) 6 | var body: some View { 7 | 📣ADView(self.targetApp, second: 10) 8 | .environmentObject(self.model) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Shared/🪧Widget/Rest/🪧ContainerBackground.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🪧ContainerBackground: ViewModifier { 4 | func body(content: Content) -> some View { 5 | if #available(iOS 17.0, watchOS 10.0, macOS 14.0, *) { 6 | content.containerBackground(.background, for: .widget) 7 | } else { 8 | content 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/apple_health_badge.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "apple_health_badge.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/apple_health_badge.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "apple_health_badge.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /iOS/App Extensions/Widget/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionPointIdentifier 8 | com.apple.widgetkit-extension 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionPointIdentifier 8 | com.apple.widgetkit-extension 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /watchOS/App Extensions/Widget/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionPointIdentifier 8 | com.apple.widgetkit-extension 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/📚ContentView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📚ContentView: View { 4 | var body: some View { 5 | NavigationStack { 6 | 📚NotesList() 7 | } 8 | .modifier(🔦FocusedModelHandler()) 9 | .modifier(📰SheetHandlerOnContentView()) 10 | .modifier(🚮DeleteAllNotesButton.ConfirmDialog()) 11 | .modifier(💬RequestUserReview()) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /macOS/App.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct MacOSApp: App { 5 | @NSApplicationDelegateAdaptor var model: 📱AppModel 6 | var body: some Scene { 7 | 📚NotesWindow() 8 | .commands { 🪄Commands() } 9 | 🗑TrashWindow() 10 | 🏗️MenuBarShortcut(self.model) 11 | 🔧Settings(self.model) 12 | ℹ️HelpWindows() 13 | 🛒InAppPurchaseWindow() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /iOS/App Extensions/Widget/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | }, 6 | { 7 | "appearances" : [ 8 | { 9 | "appearance" : "luminosity", 10 | "value" : "dark" 11 | } 12 | ], 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /watchOS/Supporting files/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | }, 6 | { 7 | "appearances" : [ 8 | { 9 | "appearance" : "luminosity", 10 | "value" : "dark" 11 | } 12 | ], 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iOS/App Extensions/Widget/Assets.xcassets/WidgetBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | }, 6 | { 7 | "appearances" : [ 8 | { 9 | "appearance" : "luminosity", 10 | "value" : "dark" 11 | } 12 | ], 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /watchOS/App Extensions/Widget/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | }, 6 | { 7 | "appearances" : [ 8 | { 9 | "appearance" : "luminosity", 10 | "value" : "dark" 11 | } 12 | ], 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iOS/📖WidgetSheet/📖DismissWidgetSheetOnBackground.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📖DismissWidgetSheetOnBackground: ViewModifier { 4 | @EnvironmentObject var model: 📱AppModel 5 | @Environment(\.scenePhase) var scenePhase 6 | func body(content: Content) -> some View { 7 | content 8 | .onChange(of: self.scenePhase) { 9 | self.model.dismissWidgetSheetOnBackground($0) 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /iOS/📥NotesImport/📥NotesImportSheetButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📥NotesImportSheetButton: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | var body: some View { 6 | Button { 7 | self.model.presentSheetOnContentView(.notesImport) 8 | } label: { 9 | Label("Import notes", systemImage: "tray.and.arrow.down") 10 | } 11 | .modifier(📚DisableInEditMode()) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /macOS/📥NotesImport/📥DismissButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📥DismissButton: ToolbarContent { 4 | @EnvironmentObject var model: 📱AppModel 5 | var body: some ToolbarContent { 6 | ToolbarItem(placement: .automatic) { 7 | Button("Dismiss", role: .cancel) { 8 | self.model.presentedSheetOnContentView = nil 9 | } 10 | .foregroundStyle(.secondary) 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /watchOS/App Extensions/Widget/Assets.xcassets/WidgetBackground.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | }, 6 | { 7 | "appearances" : [ 8 | { 9 | "appearance" : "luminosity", 10 | "value" : "dark" 11 | } 12 | ], 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/MemorizeWidget.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "mw(大).heic", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "filename" : "mw(大) 1.heic", 9 | "idiom" : "universal", 10 | "locale" : "ja" 11 | } 12 | ], 13 | "info" : { 14 | "author" : "xcode", 15 | "version" : 1 16 | }, 17 | "properties" : { 18 | "localizable" : true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /macOS/Rest/Rest/🛒InAppPurchaseCommand.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🛒InAppPurchaseCommand: Commands { 4 | @Environment(\.openWindow) var openWindow 5 | var body: some Commands { 6 | CommandGroup(before: .appVisibility) { 7 | Button(String(localized: "In-App Purchase", table: "🌐AD&InAppPurchase")) { 8 | self.openWindow(id: "InAppPurchase") 9 | } 10 | Divider() 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/MemorizeWidget.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "mw(大).heic", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "filename" : "mw(大) 1.heic", 9 | "idiom" : "universal", 10 | "locale" : "ja" 11 | } 12 | ], 13 | "info" : { 14 | "author" : "xcode", 15 | "version" : 1 16 | }, 17 | "properties" : { 18 | "localizable" : true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /watchOS/📱AppModel(extension).swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension 📱AppModel { 4 | func deleteNoteOnWidgetSheet(_ ⓘndexSet: IndexSet) { 5 | if let ⓘndex = ⓘndexSet.first { 6 | self.removeNote(self.openedWidgetNoteIDs[ⓘndex]) 7 | } 8 | } 9 | func addNewNoteOnShortcutSheet(_ ⓝote: 📗Note) { 10 | self.insertOnTop([ⓝote]) 11 | self.presentedSheetOnContentView = nil 12 | 💥Feedback.success() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/LockInNote.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "topLIN1200w(大).heic", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "filename" : "top1200w(大).heic", 9 | "idiom" : "universal", 10 | "locale" : "ja" 11 | } 12 | ], 13 | "info" : { 14 | "author" : "xcode", 15 | "version" : 1 16 | }, 17 | "properties" : { 18 | "localizable" : true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/TapWeight.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "TWtop1200wEN.heic", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "filename" : "TWtop1200wJA.heic", 9 | "idiom" : "universal", 10 | "locale" : "ja" 11 | } 12 | ], 13 | "info" : { 14 | "author" : "xcode", 15 | "version" : 1 16 | }, 17 | "properties" : { 18 | "localizable" : true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/moveBySwiping.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "Group 14(中).heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/LockInNote.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "topLIN1200w(大).heic", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "filename" : "top1200w(大).heic", 9 | "idiom" : "universal", 10 | "locale" : "ja" 11 | } 12 | ], 13 | "info" : { 14 | "author" : "xcode", 15 | "version" : 1 16 | }, 17 | "properties" : { 18 | "localizable" : true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/TapWeight.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "TWtop1200wEN.heic", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "filename" : "TWtop1200wJA.heic", 9 | "idiom" : "universal", 10 | "locale" : "ja" 11 | } 12 | ], 13 | "info" : { 14 | "author" : "xcode", 15 | "version" : 1 16 | }, 17 | "properties" : { 18 | "localizable" : true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/mock/TapTemperature.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "TTtop1200wEN.heic", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "filename" : "TTtop1200wJA.heic", 9 | "idiom" : "universal", 10 | "locale" : "ja" 11 | } 12 | ], 13 | "info" : { 14 | "author" : "xcode", 15 | "version" : 1 16 | }, 17 | "properties" : { 18 | "localizable" : true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/mock/TapTemperature.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "TTtop1200wEN.heic", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "filename" : "TTtop1200wJA.heic", 9 | "idiom" : "universal", 10 | "locale" : "ja" 11 | } 12 | ], 13 | "info" : { 14 | "author" : "xcode", 15 | "version" : 1 16 | }, 17 | "properties" : { 18 | "localizable" : true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/deleteBySwiping.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "swipeLeft Group 13(中).heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/systemFamilyExample.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "HomeScreenExample.heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/Supporting files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ITSAppUsesNonExemptEncryption 6 | 7 | UIApplicationSceneManifest 8 | 9 | UIApplicationSupportsMultipleScenes 10 | 11 | UISceneConfigurations 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/accessoryFamilyExample.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "LockScreenExample.heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/shareSheetFile.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "fileShareSheet Group 9(中).heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/systemFamilyDefault.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "systemFamilyDefault.heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/AccessoryFamilyDefault.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "AccessoryFamilyDefault.heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/shareSheetText.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "selectedTextShareSheet Group 8(中).heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/systemFamilyMultiNotes.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "systemFamilyMultiNotes.heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/systemFamilyShowComment.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "systemFamilyShowComment.heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/AccessoryFamilyMultiNotes.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "AccessoryFamilyMultiNotes.heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/AccessoryFamilyShowComment.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "AccessoryFamilyShowComment.heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/Image/importNotesButton.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "filename" : "importNotesInApp trim edit Group 12.heic", 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Shared/📥NotesImport/📥Error.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | enum 📥Error: Error { 4 | case dataSizeLimitExceeded 5 | case others(String) 6 | } 7 | 8 | extension 📥Error { 9 | func messageText() -> some View { 10 | switch self { 11 | case .dataSizeLimitExceeded: 12 | Text("Total notes data over 800kB. Please decrease notes.") 13 | case .others(let ⓛocalizedDescription): 14 | Text(ⓛocalizedDescription) 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /iOS/App Extensions/ShareExtension/📨HostingViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import SwiftUI 3 | 4 | class 📨HostingViewController: UIHostingController<📨RootView> { 5 | private let model = 📨ShareExtensionModel() 6 | 7 | required init?(coder aDecoder: NSCoder) { 8 | super.init(coder: aDecoder, rootView: 📨RootView(self.model)) 9 | } 10 | 11 | override func viewDidLoad() { 12 | super.viewDidLoad() 13 | self.model.setUp(self.extensionContext) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Shared/📗Note&Notes/📗Note.swift: -------------------------------------------------------------------------------- 1 | import WidgetKit 2 | 3 | struct 📗Note: Codable, Identifiable, Hashable { 4 | var title: String 5 | var comment: String 6 | var id: UUID 7 | init(_ title: String, _ comment: String = "") { 8 | self.title = title 9 | self.comment = comment 10 | self.id = .init() 11 | } 12 | } 13 | 14 | extension 📗Note { 15 | var isEmpty: Bool { 16 | self.title.isEmpty && self.comment.isEmpty 17 | } 18 | static var empty: Self { .init("") } 19 | } 20 | -------------------------------------------------------------------------------- /iOS/Rest/💬RequestUserReview.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 💬RequestUserReview: ViewModifier { 4 | @Environment(\.requestReview) var requestReview 5 | @AppStorage("launchCount") var launchCount: Int = 0 6 | func body(content: Content) -> some View { 7 | content 8 | .task { 9 | self.launchCount += 1 10 | if [20, 50, 100, 200].contains(self.launchCount) { 11 | self.requestReview() 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /watchOS/📰SheetHandlerOnContentView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📰SheetHandlerOnContentView: ViewModifier { 4 | @EnvironmentObject var model: 📱AppModel 5 | func body(content: Content) -> some View { 6 | content 7 | .sheet(item: self.$model.presentedSheetOnContentView) { 8 | switch $0 { 9 | case .widget: 📖WidgetSheetView() 10 | case .newNoteShortcut: 🆕NewNoteShortcutView() 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /iOS/Rest/🚮DeleteNoteButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🚮DeleteNoteButton: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | private var note: 📗Note 6 | var body: some View { 7 | Button(role: .destructive) { 8 | self.model.removeNote(self.note) 9 | } label: { 10 | Label("Delete", systemImage: "trash") 11 | .padding(8) 12 | } 13 | .hoverEffect() 14 | } 15 | init(_ note: 📗Note) { 16 | self.note = note 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /iOS/Supporting files/Assets.xcassets/AD/appstore_badge.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "appstore_badge 1.svg", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "filename" : "appstore_badge.svg", 9 | "idiom" : "universal", 10 | "locale" : "ja" 11 | } 12 | ], 13 | "info" : { 14 | "author" : "xcode", 15 | "version" : 1 16 | }, 17 | "properties" : { 18 | "localizable" : true, 19 | "preserves-vector-representation" : true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /macOS/Rest/💬RequestUserReview.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 💬RequestUserReview: ViewModifier { 4 | @Environment(\.requestReview) var requestReview 5 | @AppStorage("launchCount") private var launchCount: Int = 0 6 | func body(content: Content) -> some View { 7 | content 8 | .task { 9 | self.launchCount += 1 10 | if [30, 60, 100].contains(self.launchCount) { 11 | self.requestReview() 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AD/appstore_badge.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "appstore_badge 1.svg", 5 | "idiom" : "universal" 6 | }, 7 | { 8 | "filename" : "appstore_badge.svg", 9 | "idiom" : "universal", 10 | "locale" : "ja" 11 | } 12 | ], 13 | "info" : { 14 | "author" : "xcode", 15 | "version" : 1 16 | }, 17 | "properties" : { 18 | "localizable" : true, 19 | "preserves-vector-representation" : true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Shared/🔍Search/🔍FailureAlert.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🔍FailureAlert: ViewModifier { 4 | @ObservedObject var model: 🔍SearchModel 5 | func body(content: Content) -> some View { 6 | content 7 | .alert("⚠️ Failed to open URL", isPresented: self.$model.alertOpenURLFailure) { 8 | Button("OK") {} 9 | } message: { 10 | Text("Change the URL") 11 | } 12 | } 13 | init(_ model: 🔍SearchModel) { 14 | self.model = model 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /iOS/📖WidgetSheet/📖DeletedNoteView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📖DeletedNoteView: View { 4 | var body: some View { 5 | HStack { 6 | Spacer() 7 | VStack(spacing: 24) { 8 | Label("Deleted.", systemImage: "checkmark") 9 | Image(systemName: "trash") 10 | } 11 | .foregroundColor(.primary) 12 | .imageScale(.small) 13 | .font(.largeTitle) 14 | Spacer() 15 | } 16 | .padding(24) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /macOS/🔧Settings/🔧MenuBarPanel.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🔧MenuBarPanel: View { 4 | @AppStorage(🎛️Key.showMenuBar) var value: Bool = true 5 | var body: some View { 6 | Form { 7 | Toggle(isOn: self.$value) { 8 | Label("New note shortcut on menu bar", systemImage: "square.and.pencil") 9 | } 10 | } 11 | .formStyle(.grouped) 12 | .tabItem { 13 | Label("MenuBar", systemImage: "menubar.arrow.up.rectangle") 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /macOS/📱AppModel(NSApplicationDelegate).swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension 📱AppModel: NSApplicationDelegate { 4 | func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 5 | false 6 | } 7 | func applicationDidResignActive(_ notification: Notification) { 8 | self.saveNotes(withWidgetReload: false) 9 | } 10 | func application(_ application: NSApplication, open urls: [URL]) { 11 | if let ⓤrl = urls.first { 12 | self.handleWidgetURL(ⓤrl) 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /iOS/Rest/🆕NewNoteCommand.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🆕NewNoteCommand: Commands { 4 | @ObservedObject var model: 📱AppModel 5 | var body: some Commands { 6 | CommandGroup(replacing: .newItem) { 7 | Button { 8 | self.model.addNewNoteOnTop() 9 | } label: { 10 | Text("New note") 11 | } 12 | .keyboardShortcut("n") 13 | .disabled(self.model.selectedSidebar != .notesList) 14 | } 15 | } 16 | init(_ model: 📱AppModel) { 17 | self.model = model 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/📚NotesWindow.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📚NotesWindow: Scene { 4 | var body: some Scene { 5 | Window("Notes", id: "notes") { 6 | 📚ContentView() 7 | .frame(minWidth: Self.size.width, 8 | minHeight: Self.size.height) 9 | } 10 | .defaultSize(width: Self.size.width, 11 | height: Self.size.height) 12 | } 13 | } 14 | 15 | private extension 📚NotesWindow { 16 | private static var size: (width: CGFloat, height: CGFloat) { 17 | (380, 240) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/🔦FocusedModel/🔦FocusedModelHandler.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🔦FocusedModelHandler: ViewModifier { 4 | @EnvironmentObject var model: 📱AppModel 5 | func body(content: Content) -> some View { 6 | content 7 | .focusedValue(\.notesSelection, self.model.notesSelection) 8 | .focusedValue(\.notes, self.model.notes) 9 | .focusedValue(\.openedMainWindow, true) 10 | .focusedValue(\.presentedSheetOnContentView, self.model.presentedSheetOnContentView) 11 | .focusedObject(self.model) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /macOS/🏗️MenuBarShortcut/🏗️MenuBarShortcut.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🏗️MenuBarShortcut: Scene { 4 | @ObservedObject var model: 📱AppModel 5 | @AppStorage(🎛️Key.showMenuBar) var showMenuBar: Bool = true 6 | var body: some Scene { 7 | MenuBarExtra("New note", 8 | systemImage: "square.and.pencil", 9 | isInserted: self.$showMenuBar) { 10 | 🏗️ContentView(self.model) 11 | } 12 | .menuBarExtraStyle(.window) 13 | } 14 | init(_ model: 📱AppModel) { 15 | self.model = model 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /watchOS/Supporting files/watchOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.icloud-container-identifiers 6 | 7 | com.apple.developer.ubiquity-kvstore-identifier 8 | $(TeamIdentifierPrefix)net.aaaakkkkssssttttnnnn.MemorizeWidget 9 | com.apple.security.application-groups 10 | 11 | group.net.aaaakkkkssssttttnnnn.MemorizeWidget 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /iOS/ContentView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct ContentView: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | var body: some View { 6 | Group { 7 | switch UIDevice.current.userInterfaceIdiom { 8 | case .phone: 🔖TabView() 9 | case .pad: 🔖SplitView() 10 | default: EmptyView() 11 | } 12 | } 13 | .onOpenURL(perform: self.model.handleWidgetURL) 14 | .modifier(📰SheetHandlerOnContentView()) 15 | .modifier(💬RequestUserReview()) 16 | .environmentObject(self.model.inAppPurchaseModel) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /watchOS/App Extensions/Widget/Widget.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.icloud-container-identifiers 6 | 7 | com.apple.developer.ubiquity-kvstore-identifier 8 | $(TeamIdentifierPrefix)net.aaaakkkkssssttttnnnn.MemorizeWidget 9 | com.apple.security.application-groups 10 | 11 | group.net.aaaakkkkssssttttnnnn.MemorizeWidget 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/🛫MoveTopButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🛫MoveTopButton: View { 4 | @FocusedObject var model: 📱AppModel? 5 | private var notes: Set<📗Note> 6 | var body: some View { 7 | Button { 8 | self.model?.moveTop(self.notes) 9 | } label: { 10 | Label("Move top", systemImage: "arrow.up.to.line") 11 | } 12 | .disabled( 13 | self.notes.isEmpty 14 | || 15 | self.notes.contains { $0 == self.model?.notes.first } 16 | ) 17 | } 18 | init(_ notes: Set<📗Note>) { 19 | self.notes = notes 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/🛬MoveEndButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🛬MoveEndButton: View { 4 | @FocusedObject var model: 📱AppModel? 5 | private var notes: Set<📗Note> 6 | var body: some View { 7 | Button { 8 | self.model?.moveEnd(self.notes) 9 | } label: { 10 | Label("Move end", systemImage: "arrow.down.to.line") 11 | } 12 | .disabled( 13 | self.notes.isEmpty 14 | || 15 | self.notes.contains { $0 == self.model?.notes.last } 16 | ) 17 | } 18 | init(_ notes: Set<📗Note>) { 19 | self.notes = notes 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /macOS/🗑TrashWindow/🗑TrashWindow.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🗑TrashWindow: Scene { 4 | var body: some Scene { 5 | Window("Trash", id: "trash") { 6 | 🗑ContentView() 7 | .frame(minWidth: Self.size.width, 8 | minHeight: Self.size.height) 9 | } 10 | .defaultSize(width: Self.size.width, 11 | height: Self.size.height) 12 | .defaultPosition(.init(x: 0.75, y: 0.5)) 13 | } 14 | } 15 | 16 | private extension 🗑TrashWindow { 17 | private static var size: (width: CGFloat, height: CGFloat) { 18 | (380, 240) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iOS/📖WidgetSheet/📖DictionaryButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📖DictionaryButton: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | private var term: String 6 | var body: some View { 7 | Button { 8 | self.model.presentedSheetOnWidgetSheet = .dictionary(.init(term: self.term)) 9 | UISelectionFeedbackGenerator().selectionChanged() 10 | } label: { 11 | Label("Dictionary", systemImage: "character.book.closed") 12 | .padding(8) 13 | } 14 | .hoverEffect() 15 | } 16 | init(_ ⓝote: 📗Note) { 17 | self.term = ⓝote.title 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /iOS/📖WidgetSheet/📖WidgetSheetView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📖WidgetSheetView: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | var body: some View { 6 | NavigationStack { 7 | Group { 8 | if self.model.openedWidgetNotesCount == 1 { 9 | 📖SingleNoteLayoutView() 10 | } else { 11 | 📖MultiNotesLayoutView() 12 | } 13 | } 14 | .navigationBarTitleDisplayMode(.inline) 15 | .modifier(📰SheetOnWidgetSheet.Handler()) 16 | .toolbar { 📰DismissButton() } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /macOS/Rest/Rest/🛒InAppPurchaseWindow.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🛒InAppPurchaseWindow: Scene { 4 | var body: some Scene { 5 | Window(.init("In-App Purchase", tableName: "🌐AD&InAppPurchase"), id: "InAppPurchase") { 6 | Self.ContentView() 7 | } 8 | .defaultSize(width: 400, height: 700) 9 | .commandsRemoved() 10 | } 11 | private struct ContentView: View { 12 | @EnvironmentObject var appModel: 📱AppModel 13 | var body: some View { 14 | 🛒InAppPurchaseMenu() 15 | .environmentObject(self.appModel.inAppPurchaseModel) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /macOS/🔧Settings/🔧Settings.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🔧Settings: Scene { 4 | private var model: 📱AppModel 5 | var body: some Scene { 6 | Settings { 7 | TabView { 8 | 🔧WidgetPanel() 9 | 🔧MenuBarPanel() 10 | 🔧SearchCustomizePanel() 11 | 🔧GuidePanel() 12 | } 13 | .frame(width: 540, height: 400) 14 | .environmentObject(self.model) 15 | } 16 | .windowResizability(.contentSize) 17 | .defaultPosition(.init(x: 0.1, y: 0.1)) 18 | } 19 | init(_ model: 📱AppModel) { 20 | self.model = model 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Widget.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.icloud-container-identifiers 6 | 7 | com.apple.developer.ubiquity-kvstore-identifier 8 | $(TeamIdentifierPrefix)net.aaaakkkkssssttttnnnn.MemorizeWidget 9 | com.apple.security.app-sandbox 10 | 11 | com.apple.security.application-groups 12 | 13 | group.net.aaaakkkkssssttttnnnn.MemorizeWidget 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/👆InsertAboveButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 👆InsertAboveButton: View { 4 | @FocusedObject var model: 📱AppModel? 5 | @FocusedValue(\.editingNote) var editingNote 6 | private var notes: Set<📗Note> 7 | var body: some View { 8 | Button { 9 | self.model?.insertAbove(self.notes) 10 | } label: { 11 | Label("Insert above", systemImage: "text.insert") 12 | } 13 | .disabled( 14 | (self.notes.count != 1) 15 | || 16 | (self.editingNote?.title.isEmpty == true) 17 | ) 18 | } 19 | init(_ notes: Set<📗Note>) { 20 | self.notes = notes 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/👇InsertBelowButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 👇InsertBelowButton: View { 4 | @FocusedObject var model: 📱AppModel? 5 | @FocusedValue(\.editingNote) var editingNote 6 | private var notes: Set<📗Note> 7 | var body: some View { 8 | Button { 9 | self.model?.insertBelow(self.notes) 10 | } label: { 11 | Label("Insert below", systemImage: "text.append") 12 | } 13 | .disabled( 14 | (self.notes.count != 1) 15 | || 16 | (self.editingNote?.title.isEmpty == true) 17 | ) 18 | } 19 | init(_ notes: Set<📗Note>) { 20 | self.notes = notes 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Shared/Rest/📰SheetOnContentView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | enum 📰SheetOnContentView { 4 | case widget(🪧Tag) 5 | #if os(iOS) 6 | case notesImport 7 | #endif 8 | #if os(macOS) 9 | case notesImportFile 10 | case notesImportText 11 | #endif 12 | #if os(iOS) || os(macOS) 13 | case notesExport 14 | #endif 15 | #if os(iOS) 16 | case customizeFontSize 17 | case customizeSearch 18 | case search(URL) 19 | case dictionary(UIReferenceLibraryViewController) 20 | case aboutApp 21 | case purchase 22 | #endif 23 | #if os(watchOS) 24 | case newNoteShortcut 25 | #endif 26 | } 27 | 28 | extension 📰SheetOnContentView: Identifiable, Hashable { 29 | var id: Self { self } 30 | } 31 | -------------------------------------------------------------------------------- /watchOS/Rest/💁GuideMenu.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 💁GuideMenu: View { 4 | var body: some View { 5 | List { 6 | Section { 7 | Label("Delete a note by swiping the row.", 8 | systemImage: "cursorarrow.motionlines") 9 | Label("Move a note by drag and drop the row.", 10 | systemImage: "hand.draw") 11 | } 12 | Section { 13 | 💁GuideViewComponent.AboutDataSync() 14 | 💁GuideViewComponent.AboutDataCount() 15 | } header: { 16 | Text("Data") 17 | } 18 | } 19 | .navigationTitle("Guide") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /macOS/Supporting files/macOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.icloud-container-identifiers 6 | 7 | com.apple.developer.ubiquity-kvstore-identifier 8 | $(TeamIdentifierPrefix)$(CFBundleIdentifier) 9 | com.apple.security.app-sandbox 10 | 11 | com.apple.security.application-groups 12 | 13 | group.net.aaaakkkkssssttttnnnn.MemorizeWidget 14 | 15 | com.apple.security.files.user-selected.read-only 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /iOS/App Extensions/Widget/Widget.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.icloud-container-identifiers 6 | 7 | com.apple.developer.ubiquity-kvstore-identifier 8 | $(TeamIdentifierPrefix)net.aaaakkkkssssttttnnnn.MemorizeWidget 9 | com.apple.security.app-sandbox 10 | 11 | com.apple.security.application-groups 12 | 13 | group.net.aaaakkkkssssttttnnnn.MemorizeWidget 14 | 15 | com.apple.security.network.client 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/🚏ContextMenu.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🚏ContextMenu: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | private var ids: Set 6 | private var targetNotes: Set<📗Note> { 7 | .init(self.model.notes.filter { self.ids.contains($0.id) }) 8 | } 9 | var body: some View { 10 | 📘DictionaryButton(self.targetNotes) 11 | 🔍SearchButton(self.targetNotes) 12 | Divider() 13 | 🛫MoveTopButton(self.targetNotes) 14 | 🛬MoveEndButton(self.targetNotes) 15 | Divider() 16 | 👆InsertAboveButton(self.targetNotes) 17 | 👇InsertBelowButton(self.targetNotes) 18 | } 19 | init(_ ids: Set) { 20 | self.ids = ids 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /iOS/📰Sheet/📰DismissButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | //MARK: For sheet on ContentView 4 | struct 📰DismissButton: ToolbarContent { 5 | @EnvironmentObject var model: 📱AppModel 6 | var body: some ToolbarContent { 7 | ToolbarItem(placement: .topBarTrailing) { 8 | Button { 9 | self.model.presentedSheetOnContentView = nil 10 | UISelectionFeedbackGenerator().selectionChanged() 11 | } label: { 12 | Image(systemName: "xmark.circle.fill") 13 | .symbolRenderingMode(.hierarchical) 14 | .font(.title3) 15 | .foregroundStyle(Color.secondary) 16 | } 17 | .keyboardShortcut(.cancelAction) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iOS/App Extensions/ShareExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSExtension 6 | 7 | NSExtensionAttributes 8 | 9 | NSExtensionActivationRule 10 | 11 | NSExtensionActivationSupportsFileWithMaxCount 12 | 1 13 | NSExtensionActivationSupportsText 14 | 15 | 16 | 17 | NSExtensionMainStoryboard 18 | MainInterface 19 | NSExtensionPointIdentifier 20 | com.apple.share-services 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/🔍SearchButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🔍SearchButton: View { 4 | @StateObject var searchModel: 🔍SearchModel = .init() 5 | @Environment(\.openURL) var openURL 6 | private var notes: Set<📗Note> 7 | var body: some View { 8 | Button { 9 | guard let ⓠuery = self.notes.first?.title else { 10 | NSSound.beep() 11 | return 12 | } 13 | self.openURL(self.searchModel.generateURL(ⓠuery)) 14 | } label: { 15 | Label("Search", systemImage: "magnifyingglass") 16 | } 17 | .disabled(self.notes.count != 1) 18 | .modifier(🔍FailureAlert(self.searchModel)) 19 | } 20 | init(_ notes: Set<📗Note>) { 21 | self.notes = notes 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /iOS/Supporting files/iOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.icloud-container-identifiers 6 | 7 | com.apple.developer.ubiquity-kvstore-identifier 8 | $(TeamIdentifierPrefix)$(CFBundleIdentifier) 9 | com.apple.security.app-sandbox 10 | 11 | com.apple.security.application-groups 12 | 13 | group.net.aaaakkkkssssttttnnnn.MemorizeWidget 14 | 15 | com.apple.security.files.user-selected.read-write 16 | 17 | com.apple.security.network.client 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "platform" : "universal", 6 | "reference" : "systemCyanColor" 7 | }, 8 | "idiom" : "universal" 9 | }, 10 | { 11 | "appearances" : [ 12 | { 13 | "appearance" : "luminosity", 14 | "value" : "dark" 15 | } 16 | ], 17 | "color" : { 18 | "color-space" : "display-p3", 19 | "components" : { 20 | "alpha" : "1.000", 21 | "blue" : "0.600", 22 | "green" : "0.400", 23 | "red" : "0.200" 24 | } 25 | }, 26 | "idiom" : "universal" 27 | } 28 | ], 29 | "info" : { 30 | "author" : "xcode", 31 | "version" : 1 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Shared/💾Data/🩹WorkaroundOnIOS15.swift: -------------------------------------------------------------------------------- 1 | import WidgetKit 2 | 3 | enum 🩹WorkaroundOnIOS15 { 4 | enum SyncWidget { 5 | static func save(_ ⓝotes: 📚Notes) { 6 | #if os(iOS) 7 | if #available(iOS 16, *) { 8 | 💾UserDefaults.appGroup.removeObject(forKey: "SyncBetweenWidgetOnIOS15") 9 | } else { 10 | 💾UserDefaults.appGroup.set(ⓝotes.encode(), forKey: "SyncBetweenWidgetOnIOS15") 11 | WidgetCenter.shared.reloadAllTimelines() 12 | } 13 | #endif 14 | } 15 | #if os(iOS) 16 | static func loadNotes() -> 📚Notes? { 17 | guard let ⓓata = 💾UserDefaults.appGroup.data(forKey: "SyncBetweenWidgetOnIOS15") else { return nil } 18 | return 📚Notes.decode(ⓓata) 19 | } 20 | #endif 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /macOS/Rest/📣ADSheet.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📣ADSheet: ViewModifier { 4 | @EnvironmentObject var appModel: 📱AppModel 5 | @State private var targetApp: 📣ADTargetApp = .pickUpAppWithout(.MemorizeWidget) 6 | @State private var showSheet: Bool = false 7 | func body(content: Content) -> some View { 8 | content 9 | .sheet(isPresented: self.$showSheet) { 10 | 📣ADContent(self.targetApp, second: 8) 11 | .environmentObject(self.appModel.inAppPurchaseModel) 12 | } 13 | .task { 14 | try? await Task.sleep(for: .seconds(0.5)) 15 | if self.appModel.inAppPurchaseModel.checkToShowADSheet() { 16 | self.showSheet = true 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/📘DictionaryButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📘DictionaryButton: View { 4 | @Environment(\.openURL) var openURL 5 | private var notes: Set<📗Note> 6 | var body: some View { 7 | Button { 8 | guard let ⓝote = self.notes.first, 9 | let ⓟath = ⓝote.title.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed), 10 | let ⓤrl = URL(string: "dict://" + ⓟath) else { 11 | NSSound.beep() 12 | return 13 | } 14 | self.openURL(ⓤrl) 15 | } label: { 16 | Label("Look up in dictionary", systemImage: "character.book.closed") 17 | } 18 | .disabled(self.notes.count != 1) 19 | } 20 | init(_ notes: Set<📗Note>) { 21 | self.notes = notes 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/📰SheetHandlerOnContentView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📰SheetHandlerOnContentView: ViewModifier { 4 | @EnvironmentObject var model: 📱AppModel 5 | func body(content: Content) -> some View { 6 | content 7 | .sheet(item: self.$model.presentedSheetOnContentView) { 8 | switch $0 { 9 | case .widget: 📖WidgetSheetView() 10 | case .notesImportFile: 📥NotesImportFileSheetView() 11 | case .notesImportText: 📥NotesImportTextSheetView() 12 | case .notesExport: 📤NotesExportSheetView() 13 | } 14 | } 15 | .onChange(of: self.model.presentedSheetOnContentView) { 16 | if $0 != nil { self.model.clearSelection() } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Shared/📥NotesImport/📥SeparatorPicker.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📥SeparatorPicker: View { 4 | @EnvironmentObject var model: 📥NotesImportModel 5 | var body: some View { 6 | Picker(selection: self.$model.separator) { 7 | Text("Tab ␣ ") 8 | .tag(📚TextConvert.Separator.tab) 9 | .accessibilityLabel("Tab") 10 | Text("Comma , ") 11 | .tag(📚TextConvert.Separator.comma) 12 | .accessibilityLabel("Comma") 13 | Text("(Title only)") 14 | .tag(📚TextConvert.Separator.titleOnly) 15 | .accessibilityLabel("Title only") 16 | } label: { 17 | Label("Separator", 18 | systemImage: "arrowtriangle.left.and.line.vertical.and.arrowtriangle.right") 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iOS/App Extensions/ShareExtension/ShareExtension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.icloud-container-identifiers 6 | 7 | com.apple.developer.ubiquity-kvstore-identifier 8 | $(TeamIdentifierPrefix)net.aaaakkkkssssttttnnnn.MemorizeWidget 9 | com.apple.security.app-sandbox 10 | 11 | com.apple.security.application-groups 12 | 13 | group.net.aaaakkkkssssttttnnnn.MemorizeWidget 14 | 15 | com.apple.security.files.user-selected.read-write 16 | 17 | com.apple.security.network.client 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Shared/Supporting files/Archive/memo.md: -------------------------------------------------------------------------------- 1 | ## REJECT .defaultAppStorage(UserDefaults(suiteName: `AppGroupID`)!) 2 | reason: buggy list-animation on iOS15.x 3 | 4 | ## Size limitation 5 | > [User Defaults] CFPrefsPlistSource<0x2838db480> (Domain: group.net.aaaakkkkssssttttnnnn.MemorizeWidget, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null), Contents Need Refresh: No): Attempting to store >= 4194304 bytes of data in CFPreferences/NSUserDefaults on this platform is invalid. This is a bug in MemorizeWidget or a library it uses. 6 | Description of keys being set: 7 | > Notes: data value, size: 4521029 8 | > 9 | > Description of keys already present: 10 | > Notes: data value, size: 4173442 11 | > TrashBox: data value, size: 498 12 | > DeletedContents: data value, size: 309 13 | > savedDataByShareExtension: boolean value 14 | > savedByExtension: boolean value 15 | -------------------------------------------------------------------------------- /iOS/🔍Search/🔍SearchSheetView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import SafariServices 3 | 4 | struct 🔍SearchSheetView: View { 5 | private var url: URL 6 | var body: some View { 7 | Self.UIKitView(url: self.url) 8 | .ignoresSafeArea() 9 | .presentationDetents([.height(550)]) 10 | } 11 | init(_ url: URL) { 12 | self.url = url 13 | } 14 | } 15 | 16 | private extension 🔍SearchSheetView { 17 | private struct UIKitView: UIViewControllerRepresentable { 18 | var url: URL 19 | func makeUIViewController(context: Context) -> SFSafariViewController { 20 | .init(url: self.url) 21 | } 22 | func updateUIViewController(_ uiViewController: SFSafariViewController, 23 | context: Context) { 24 | /* Nothing to do */ 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /iOS/🎛️Option/🎛️BeforeAfterImages.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🎛️BeforeAfterImages: View { 4 | private var before: ImageResource 5 | private var after: ImageResource 6 | var body: some View { 7 | HStack { 8 | Image(self.before) 9 | .resizable() 10 | .aspectRatio(contentMode: .fit) 11 | Image(systemName: "arrow.right") 12 | .font(.title2.weight(.semibold)) 13 | .foregroundStyle(.secondary) 14 | Image(self.after) 15 | .resizable() 16 | .aspectRatio(contentMode: .fit) 17 | } 18 | .frame(maxHeight: 170) 19 | .environment(\.layoutDirection, .leftToRight) 20 | } 21 | init(_ before: ImageResource, _ after: ImageResource) { 22 | self.before = before 23 | self.after = after 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /iOS/📰Sheet/📰SheetOnWidgetSheet.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | enum 📰SheetOnWidgetSheet { 4 | case search(URL) 5 | case dictionary(UIReferenceLibraryViewController) 6 | case ad 7 | } 8 | 9 | extension 📰SheetOnWidgetSheet: Identifiable, Hashable { 10 | var id: Self { self } 11 | struct Handler: ViewModifier { 12 | @EnvironmentObject var model: 📱AppModel 13 | func body(content: Content) -> some View { 14 | content 15 | .sheet(item: self.$model.presentedSheetOnWidgetSheet) { 16 | switch $0 { 17 | case .search(let ⓤrl): 🔍SearchSheetView(ⓤrl) 18 | case .dictionary(let ⓥiewController): 📘DictionarySheetView(ⓥiewController) 19 | case .ad: 📣ADContentView() 20 | } 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /iOS/🎛️Option/🎛️CommentOnWidgetOption.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🎛️CommentOnWidgetOption: View { 4 | var body: some View { 5 | Section { 6 | 🎛️ViewComponent.ShowCommentToggle() 7 | .padding(.vertical, 8) 8 | VStack(spacing: 16) { 9 | 🎛️BeforeAfterImages(.systemFamilyDefault, .systemFamilyShowComment) 10 | if Self.showAccessoryFamilyPreview { 11 | 🎛️BeforeAfterImages(.accessoryFamilyDefault, .accessoryFamilyShowComment) 12 | } 13 | } 14 | .padding() 15 | } 16 | } 17 | } 18 | 19 | private extension 🎛️CommentOnWidgetOption { 20 | private static var showAccessoryFamilyPreview: Bool { 21 | if #available(iOS 17.0, *) { 22 | true 23 | } else { 24 | UIDevice.current.userInterfaceIdiom == .phone 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /iOS/🎛️Option/🎛️MultiNotesOnWidgetOption.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🎛️MultiNotesOnWidgetOption: View { 4 | var body: some View { 5 | Section { 6 | 🎛️ViewComponent.MultiNotesToggle() 7 | .padding(.vertical, 8) 8 | VStack(spacing: 16) { 9 | 🎛️BeforeAfterImages(.systemFamilyDefault, .systemFamilyMultiNotes) 10 | if Self.showAccessoryFamilyPreview { 11 | 🎛️BeforeAfterImages(.accessoryFamilyDefault, .accessoryFamilyMultiNotes) 12 | } 13 | } 14 | .padding() 15 | } 16 | } 17 | } 18 | 19 | private extension 🎛️MultiNotesOnWidgetOption { 20 | private static var showAccessoryFamilyPreview: Bool { 21 | if #available(iOS 17.0, *) { 22 | true 23 | } else { 24 | UIDevice.current.userInterfaceIdiom == .phone 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Shared/💾Data/💾ICloud.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum 💾ICloud { 4 | static var api: NSUbiquitousKeyValueStore { .default } 5 | static func addObserver(_ ⓞbserver: Any, _ ⓢelector: Selector) { 6 | NotificationCenter 7 | .default 8 | .addObserver(ⓞbserver, 9 | selector: ⓢelector, 10 | name: NSUbiquitousKeyValueStore.didChangeExternallyNotification, 11 | object: Self.api) 12 | } 13 | static func save(_ ⓝotes: 📚Notes) { 14 | Self.api.set(ⓝotes.encode(), forKey: "Notes") 15 | 🩹WorkaroundOnIOS15.SyncWidget.save(ⓝotes) 16 | } 17 | static func loadNotes() -> 📚Notes? { 18 | if let ⓓata = Self.api.data(forKey: "Notes") { 19 | .decode(ⓓata) 20 | } else { 21 | nil 22 | } 23 | } 24 | static var notesIsNil: Bool { 25 | Self.loadNotes() == nil 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /macOS/📖WidgetSheet/📖MoveEndButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📖MoveEndButton: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | private var note: 📗Note 6 | @State private var done: Bool = false 7 | var body: some View { 8 | if !self.model.randomMode { 9 | Button { 10 | self.model.moveEnd([self.note]) 11 | withAnimation(.default.speed(2)) { self.done = true } 12 | } label: { 13 | Label("Move end", systemImage: "arrow.down.to.line") 14 | } 15 | .disabled(self.model.notes.last == self.note) 16 | .opacity(self.done ? 0 : 1) 17 | .overlay { 18 | if self.done { 19 | Image(systemName: "checkmark") 20 | .fontWeight(.semibold) 21 | } 22 | } 23 | } 24 | } 25 | init(_ note: 📗Note) { 26 | self.note = note 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /iOS/📥NotesImport/📥FileImportSection.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📥FileImportSection: View { 4 | @EnvironmentObject var model: 📥NotesImportModel 5 | var body: some View { 6 | Section { 7 | 📥SeparatorPicker() 8 | Button { 9 | self.model.showFileImporter.toggle() 10 | } label: { 11 | Label("Import a text-encoded file", systemImage: "folder.badge.plus") 12 | .padding(.vertical, 8) 13 | } 14 | .fileImporter(isPresented: self.$model.showFileImporter, 15 | allowedContentTypes: [.text]) { 16 | self.model.fileImporterAction($0) 17 | } 18 | .alert("⚠️ Error", isPresented: self.$model.alertError) { 19 | Button("OK") { self.model.caughtError = nil } 20 | } message: { 21 | self.model.caughtError?.messageText() 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /iOS/Rest/ℹ️AboutAppTab.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct ℹ️AboutAppTab: View { 4 | var body: some View { 5 | NavigationStack { 6 | List { 7 | Section { 8 | ℹ️IconAndName() 9 | ℹ️AppStoreLink() 10 | NavigationLink { 11 | List { 12 | ℹ️AboutAppContent() 13 | } 14 | .navigationTitle(.init("About App", tableName: "🌐AboutApp")) 15 | } label: { 16 | Label(String(localized: "About App", table: "🌐AboutApp"), 17 | systemImage: "doc") 18 | } 19 | } 20 | 🛒InAppPurchaseMenuLink() 21 | } 22 | .navigationTitle("App") 23 | //.navigationBarTitleDisplayMode(.inline) 24 | //↑ WorkaroundIOS17Bug(navigationTitleMode/navigationLinkPotision) 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /iOS/📖WidgetSheet/📖MoveEndButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📖MoveEndButton: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | private var note: 📗Note 6 | @State private var done: Bool = false 7 | var body: some View { 8 | Button { 9 | self.model.moveEnd(self.note) 10 | withAnimation(.default.speed(1.5)) { self.done = true } 11 | } label: { 12 | Label("Move end", systemImage: "arrow.down.to.line") 13 | .padding(8) 14 | } 15 | .hoverEffect() 16 | .disabled(self.model.notes.last == self.note) 17 | .opacity(self.done ? 0 : 1) 18 | .overlay { 19 | if self.done { 20 | Image(systemName: "checkmark.circle.fill") 21 | .imageScale(.large) 22 | .fontWeight(.heavy) 23 | .foregroundStyle(.tertiary) 24 | } 25 | } 26 | } 27 | init(_ note: 📗Note) { 28 | self.note = note 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /iOS/Rest/📘DictionarySheetView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📘DictionarySheetView: View { 4 | private var viewController: UIReferenceLibraryViewController 5 | var body: some View { 6 | Self.UIKitView(viewController: self.viewController) 7 | .ignoresSafeArea() 8 | .presentationDetents([.height(550)]) 9 | } 10 | init(_ referenceLibraryViewController: UIReferenceLibraryViewController) { 11 | self.viewController = referenceLibraryViewController 12 | } 13 | } 14 | 15 | private extension 📘DictionarySheetView { 16 | private struct UIKitView: UIViewControllerRepresentable { 17 | var viewController: UIReferenceLibraryViewController 18 | func makeUIViewController(context: Context) -> UIReferenceLibraryViewController { 19 | self.viewController 20 | } 21 | func updateUIViewController(_ uiViewController: UIReferenceLibraryViewController, 22 | context: Context) { 23 | /* Nothing to do */ 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Shared/🎛️Option/🎛️Key.swift: -------------------------------------------------------------------------------- 1 | enum 🎛️Key { 2 | static let multiNotesMode = "multiNotes" 3 | static let randomMode = "RandomMode" 4 | static let showCommentMode = "ShowComment" 5 | static let multilineTextAlignment = "multilineTextAlignment" 6 | enum Import { 7 | static let inputMode = "InputMode" 8 | static let textSeparator = "separator" 9 | } 10 | enum Search { 11 | static let leadingText = "SearchLeadingText" 12 | static let trailingText = "SearchTrailingText" 13 | static let openURLInOtherApp = "openURLInOtherApp" 14 | } 15 | enum FontSize { 16 | static let customize = "customizeFontSize" 17 | enum SystemFamily { 18 | static let title = "titleSizeForSystemFamily" 19 | static let comment = "commentSizeForSystemFamily" 20 | } 21 | enum AccessoryFamily { 22 | static let title = "titleSizeForAccessoryFamily" 23 | static let comment = "commentSizeForAccessoryFamily" 24 | } 25 | } 26 | #if os(macOS) 27 | static let showMenuBar = "showMenuBar" 28 | #endif 29 | } 30 | -------------------------------------------------------------------------------- /macOS/📖WidgetSheet/📖WidgetSheetView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📖WidgetSheetView: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | @State private var openedWidgetNoteIDsCache: [UUID] = [] 6 | var body: some View { 7 | NavigationStack { 8 | VStack(spacing: 0) { 9 | ForEach(self.openedWidgetNoteIDsCache, id: \.self) { 10 | 📖NoteRow($0, self.openedWidgetNoteIDsCache) 11 | } 12 | } 13 | .padding(.vertical, 28) 14 | .padding(.horizontal, 40) 15 | .frame(width: 500) 16 | .toolbar { Button("Dismiss") { self.model.presentedSheetOnContentView = nil } } 17 | } 18 | .modifier(📣ADSheet()) 19 | .animation(.default, value: self.model.presentedSheetOnContentView) 20 | .onAppear { self.openedWidgetNoteIDsCache = self.model.openedWidgetNoteIDs } 21 | .onChange(of: self.model.openedWidgetNoteIDs) { 22 | if !$0.isEmpty { self.openedWidgetNoteIDsCache = $0 } 23 | } 24 | .onDisappear { self.model.saveNotes() } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Shared/Rest/💁GuideViewComponent.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | enum 💁GuideViewComponent { 4 | struct AboutDataSync: View { 5 | var body: some View { 6 | Label("Sync notes between devices by iCloud.", systemImage: "icloud") 7 | Label("Data limitation is 1 mega byte.", systemImage: "exclamationmark.icloud") 8 | Label("If the data size is exceeded, please reduce the number of notes or clear the trash.", 9 | systemImage: "externaldrive.badge.xmark") 10 | } 11 | } 12 | struct AboutDataCount: View { 13 | @EnvironmentObject var model: 📱AppModel 14 | var body: some View { 15 | LabeledContent { 16 | Text(self.model.notes.dataCount.formatted(.byteCount(style: .file))) 17 | } label: { 18 | Label("Notes data count", systemImage: "books.vertical") 19 | } 20 | if self.model.notes.exceedDataSizePerhaps { 21 | Text("⚠️ NOTICE DATA LIMITATION") 22 | .font(.headline) 23 | .foregroundStyle(.red) 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/InfoPlist.xcstrings: -------------------------------------------------------------------------------- 1 | { 2 | "sourceLanguage" : "en", 3 | "strings" : { 4 | "CFBundleDisplayName" : { 5 | "comment" : "Bundle display name", 6 | "extractionState" : "extracted_with_value", 7 | "localizations" : { 8 | "en" : { 9 | "stringUnit" : { 10 | "state" : "new", 11 | "value" : "MacOSWidget" 12 | } 13 | } 14 | } 15 | }, 16 | "CFBundleName" : { 17 | "comment" : "Bundle name", 18 | "extractionState" : "extracted_with_value", 19 | "localizations" : { 20 | "en" : { 21 | "stringUnit" : { 22 | "state" : "new", 23 | "value" : "Widget(macOS)" 24 | } 25 | } 26 | } 27 | }, 28 | "NSHumanReadableCopyright" : { 29 | "comment" : "Copyright (human-readable)", 30 | "extractionState" : "extracted_with_value", 31 | "localizations" : { 32 | "en" : { 33 | "stringUnit" : { 34 | "state" : "new", 35 | "value" : "" 36 | } 37 | } 38 | } 39 | } 40 | }, 41 | "version" : "1.0" 42 | } -------------------------------------------------------------------------------- /Shared/💾Data/💾UserDefaults.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum 💾UserDefaults { 4 | static var appGroup: UserDefaults { 5 | if let ⓥalue = UserDefaults(suiteName: "group.net.aaaakkkkssssttttnnnn.MemorizeWidget") { 6 | return ⓥalue 7 | } else { 8 | assertionFailure(); return .standard 9 | } 10 | } 11 | } 12 | 13 | extension 💾UserDefaults { 14 | //static func save(_ ⓝotes: 📚Notes) { //Ver 1.1.2 15 | // do { 16 | // let ⓓata = try JSONEncoder().encode(ⓝotes) 17 | // Self.appGroup.set(ⓓata, forKey: "Notes") 18 | // } catch { 19 | // print(error); assertionFailure() 20 | // } 21 | //} 22 | static func loadNotesOfVer_1_1_2() -> 📚Notes? { 23 | guard let ⓓata = Self.appGroup.data(forKey: "Notes") else { return nil } 24 | return 📚Notes.decode(ⓓata) 25 | } 26 | } 27 | 28 | extension 💾UserDefaults { 29 | static var notesVer_1_1_2_IsNil: Bool { 30 | Self.loadNotesOfVer_1_1_2() == nil 31 | } 32 | static func clearNotesOfVer_1_1_2() { 33 | Self.appGroup.removeObject(forKey: "Notes") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /iOS/📖WidgetSheet/📖SearchButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📖SearchButton: View { 4 | @EnvironmentObject var appModel: 📱AppModel 5 | @StateObject var searchModel: 🔍SearchModel = .init() 6 | @Environment(\.openURL) var openURL 7 | private var query: String 8 | var body: some View { 9 | Button { 10 | let ⓤrl = self.searchModel.generateURL(self.query) 11 | if self.searchModel.openURLInOtherApp { 12 | self.openURL(ⓤrl) { 13 | if $0 == false { self.searchModel.alertOpenURLFailure = true } 14 | } 15 | } else { 16 | self.appModel.presentedSheetOnWidgetSheet = .search(ⓤrl) 17 | } 18 | UISelectionFeedbackGenerator().selectionChanged() 19 | } label: { 20 | Label("Search", systemImage: "magnifyingglass") 21 | .padding(8) 22 | } 23 | .disabled(!self.searchModel.ableInAppSearch) 24 | .hoverEffect() 25 | .modifier(🔍FailureAlert(self.searchModel)) 26 | } 27 | init(_ ⓝote: 📗Note) { 28 | self.query = ⓝote.title 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Shared/🎛️Option/🎛️Option.swift: -------------------------------------------------------------------------------- 1 | enum 🎛️Option { 2 | static var multiNotesMode: Bool { 💾UserDefaults.appGroup.bool(forKey: 🎛️Key.multiNotesMode) } 3 | static var randomMode: Bool { 💾UserDefaults.appGroup.bool(forKey: 🎛️Key.randomMode) } 4 | static var showCommentMode: Bool { 💾UserDefaults.appGroup.bool(forKey: 🎛️Key.showCommentMode) } 5 | static var multilineTextAlignment: 🎛️MultilineTextAlignment { .loadUserDeaults() } 6 | static var customizeFontSize: Bool { 💾UserDefaults.appGroup.bool(forKey: 🎛️Key.FontSize.customize) } 7 | enum FontSize { 8 | enum SystemFamily { 9 | static var title: Int { 💾UserDefaults.appGroup.integer(forKey: 🎛️Key.FontSize.SystemFamily.title) } 10 | static var comment: Int { 💾UserDefaults.appGroup.integer(forKey: 🎛️Key.FontSize.SystemFamily.comment) } 11 | } 12 | enum AccessoryFamily { 13 | static var title: Int { 💾UserDefaults.appGroup.integer(forKey: 🎛️Key.FontSize.AccessoryFamily.title) } 14 | static var comment: Int { 💾UserDefaults.appGroup.integer(forKey: 🎛️Key.FontSize.AccessoryFamily.comment) } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /iOS/📚NotesListTab/📚NotesMenuButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📚NotesMenuButton: ToolbarContent { // 🪄 4 | @EnvironmentObject var model: 📱AppModel 5 | let placement: ToolbarItemPlacement 6 | var body: some ToolbarContent { 7 | ToolbarItem(placement: self.placement) { 8 | Menu { 9 | if UIDevice.current.userInterfaceIdiom == .phone { 10 | 📥NotesImportSheetButton() 11 | } 12 | self.notesExportSheetButton() 13 | Divider() 14 | 🚮DeleteAllNotesButton() 15 | } label: { 16 | Label("Menu", systemImage: "wand.and.rays") 17 | } 18 | .modifier(🚮DeleteAllNotesButton.ConfirmDialog()) 19 | .modifier(📚DisableInEditMode()) 20 | } 21 | } 22 | } 23 | 24 | private extension 📚NotesMenuButton { 25 | private func notesExportSheetButton() -> some View { 26 | Button { 27 | self.model.presentSheetOnContentView(.notesExport) 28 | } label: { 29 | Label("Export notes", systemImage: "tray.and.arrow.up") 30 | } 31 | .disabled(self.model.notes.isEmpty) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /macOS/Rest/Rest/ℹ️HelpCommands.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct ℹ️HelpCommands: Commands { 4 | @Environment(\.openWindow) var openWindow 5 | var body: some Commands { 6 | CommandGroup(replacing: .help) { EmptyView() } 7 | CommandGroup(after: .help) { 8 | Link(String(localized: "Open App Store page", table: "🌐AboutApp"), destination: 🗒️StaticInfo.appStoreProductURL) 9 | Link(String(localized: "Review on App Store", table: "🌐AboutApp"), destination: 🗒️StaticInfo.appStoreUserReviewURL) 10 | Divider() 11 | Button(String(localized: "Description", table: "🌐AboutApp")) { self.openWindow(id: "Description") } 12 | Button(String(localized: "Privacy Policy", table: "🌐AboutApp")) { self.openWindow(id: "PrivacyPolicy") } 13 | Button(String(localized: "Version History", table: "🌐AboutApp")) { self.openWindow(id: "VersionHistory") } 14 | Divider() 15 | Button(String(localized: "Source code", table: "🌐AboutApp")) { self.openWindow(id: "SourceCode") } 16 | Button(String(localized: "Developer / Publisher", table: "🌐AboutApp")) { self.openWindow(id: "DeveloperPublisher") } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /macOS/🔧Settings/🔧WidgetPanel.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🔧WidgetPanel: View { 4 | @AppStorage(🎛️Key.FontSize.customize, store: .ⓐppGroup) var customizeFontSize: Bool = false 5 | var body: some View { 6 | Form { 7 | Section { 8 | 🎛️RandomModeToggle() 9 | } footer: { 10 | 🎛️RandomModeToggle.Caption() 11 | .foregroundStyle(.secondary) 12 | } 13 | Section { 14 | 🎛️ViewComponent.ShowCommentToggle() 15 | 🎛️ViewComponent.MultiNotesToggle() 16 | 🎛️ViewComponent.MultilineTextAlignmentPicker() 17 | } 18 | Section { 19 | 🎛️ViewComponent.FontSize.CustomizeToggle() 20 | if self.customizeFontSize { 21 | 🎛️ViewComponent.FontSize.TitleForSystemFamilyPicker() 22 | 🎛️ViewComponent.FontSize.CommentForSystemFamilyPicker() 23 | } 24 | } 25 | } 26 | .formStyle(.grouped) 27 | .animation(.default, value: self.customizeFontSize) 28 | .tabItem { 29 | Label("Widget", systemImage: "rectangle.3.group") 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /watchOS/Rest/🆕NewNoteShortcut.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🆕NewNoteShortcutView: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | @State private var note: 📗Note = .empty 6 | var body: some View { 7 | List { 8 | TextField("Title", text: self.$note.title) 9 | .font(.headline) 10 | TextField("Comment", text: self.$note.comment) 11 | .font(.subheadline) 12 | .opacity(self.note.title.isEmpty ? 0.33 : 1) 13 | self.submitButton() 14 | } 15 | .animation(.default, value: self.note.title.isEmpty) 16 | .onDisappear { self.note = .empty } 17 | } 18 | } 19 | 20 | private extension 🆕NewNoteShortcutView { 21 | private func submitButton() -> some View { 22 | Section { 23 | Button { 24 | self.model.addNewNoteOnShortcutSheet(self.note) 25 | } label: { 26 | Label("Done", systemImage: "checkmark") 27 | } 28 | .buttonStyle(.bordered) 29 | .listRowBackground(Color.clear) 30 | .fontWeight(.semibold) 31 | .disabled(self.note.title.isEmpty) 32 | .foregroundStyle(self.note.title.isEmpty ? .tertiary : .primary) 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Shared/Rest/💥Feedback.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | #if os(watchOS) 3 | import WatchKit 4 | #endif 5 | 6 | enum 💥Feedback { 7 | #if os(iOS) 8 | static func light() { 9 | UISelectionFeedbackGenerator().selectionChanged() 10 | } 11 | static func success() { 12 | UINotificationFeedbackGenerator().notificationOccurred(.success) 13 | } 14 | static func error() { 15 | UINotificationFeedbackGenerator().notificationOccurred(.error) 16 | } 17 | static func warning() { 18 | UINotificationFeedbackGenerator().notificationOccurred(.warning) 19 | } 20 | #elseif os(watchOS) 21 | static func light() { 22 | WKInterfaceDevice.current().play(.click) 23 | } 24 | static func success() { 25 | WKInterfaceDevice.current().play(.success) 26 | } 27 | static func error() { 28 | WKInterfaceDevice.current().play(.failure) 29 | } 30 | static func warning() { 31 | WKInterfaceDevice.current().play(.success) 32 | } 33 | #elseif os(macOS) 34 | static func light() { 35 | /* Nothing */ 36 | } 37 | static func success() { 38 | /* Nothing */ 39 | } 40 | static func error() { 41 | /* Nothing */ 42 | } 43 | static func warning() { 44 | /* Nothing */ 45 | } 46 | #endif 47 | } 48 | -------------------------------------------------------------------------------- /Shared/🪧Widget/🪧SubWidget.swift: -------------------------------------------------------------------------------- 1 | import WidgetKit 2 | import SwiftUI 3 | 4 | struct 🪧SubWidget: Widget { 5 | var body: some WidgetConfiguration { 6 | StaticConfiguration(kind: "sub", provider: 🪧Provider(kind: .sub)) { 7 | 🪧EntryView($0) 8 | } 9 | .configurationDisplayName("Sub widget") 10 | .description("This is spare widget for the purpose of second widget") 11 | .contentMarginsDisabled() 12 | .supportedFamilies(Self.families) 13 | } 14 | } 15 | 16 | private extension 🪧SubWidget { 17 | private static var families: [WidgetFamily] { 18 | var ⓥalue: [WidgetFamily] = [] 19 | #if os(iOS) 20 | ⓥalue.append(contentsOf: [.accessoryCircular, .accessoryRectangular, 21 | .systemSmall, .systemMedium]) 22 | if UIDevice.current.userInterfaceIdiom == .pad { 23 | ⓥalue.append(contentsOf: [.systemLarge, .systemExtraLarge]) 24 | } 25 | #elseif os(watchOS) 26 | ⓥalue.append(contentsOf: [.accessoryCircular, .accessoryRectangular, .accessoryCorner]) 27 | #elseif os(macOS) 28 | ⓥalue.append(contentsOf: [.systemSmall, .systemMedium, .systemLarge]) 29 | if #available(macOS 14.0, *) { ⓥalue.append(.systemExtraLarge) } 30 | #endif 31 | return ⓥalue 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /iOS/Rest/🩹Workaround.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | enum 🩹Workaround { 4 | struct CloseMenePopup: ViewModifier { 5 | @EnvironmentObject var model: 📱AppModel 6 | @Environment(\.scenePhase) var scenePhase 7 | func body(content: Content) -> some View { 8 | content 9 | .onChange(of: self.scenePhase) { [scenePhase] ⓝewValue in 10 | guard self.notPresentedSheet else { return } 11 | if scenePhase == .active, ⓝewValue == .inactive { 12 | self.closeMenuPopup() 13 | } 14 | } 15 | } 16 | private func closeMenuPopup() { 17 | let ⓦindowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene 18 | ⓦindowScene?.windows.first?.rootViewController?.dismiss(animated: true) 19 | } 20 | private var notPresentedSheet: Bool { 21 | self.model.presentedSheetOnContentView == nil 22 | //Prevent to dismiss sheet because of inAppPurchase dialog 23 | } 24 | //Conflict error Menu-popup / sheetPresentation 25 | //> [Presentation] 26 | //> Attempt to present <_> on <_> (from <_>) 27 | //> which is already presenting <_UIContextMenuActionsOnlyViewController: _>. 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Shared/🪧Widget/🪧Tag.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum 🪧Tag { 4 | case notes([UUID]) 5 | case newNoteShortcut 6 | case placeholder 7 | } 8 | 9 | extension 🪧Tag: Hashable { 10 | func encode() -> URL { 11 | switch self { 12 | case .notes(let ⓘds): 13 | var ⓟath: String = "" 14 | for ⓘd in ⓘds { 15 | ⓟath += ⓘd.uuidString 16 | if ⓘd == ⓘds.last { break } 17 | ⓟath += "/" 18 | } 19 | return .init(string: "example://notes/\(ⓟath)")! 20 | case .newNoteShortcut: 21 | return .init(string: "example://newNoteShortcut/")! 22 | case .placeholder: 23 | return .init(string: "example://placeholder/")! 24 | } 25 | } 26 | static func decode(_ ⓤrl: URL) -> Self? { 27 | switch ⓤrl.host { 28 | case "notes": 29 | return Self.notes(ⓤrl.pathComponents.compactMap { .init(uuidString: $0) }) 30 | case "newNoteShortcut": 31 | return Self.newNoteShortcut 32 | case "placeholder": 33 | return Self.placeholder 34 | default: 35 | assertionFailure() 36 | return nil 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /macOS/🔧Settings/🔧GuidePanel.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🔧GuidePanel: View { 4 | var body: some View { 5 | Form { 6 | Section { 7 | 💁GuideViewComponent.AboutDataSync() 8 | 💁GuideViewComponent.AboutDataCount() 9 | } header: { 10 | Text("Data") 11 | } 12 | Self.AppleSupportLinkSection() 13 | } 14 | .formStyle(.grouped) 15 | .tabItem { 16 | Label("Guide", systemImage: "questionmark") 17 | } 18 | } 19 | } 20 | 21 | private extension 🔧GuidePanel { 22 | private struct AppleSupportLinkSection: View { 23 | private static var urlString: String { 24 | "https://support.apple.com/guide/mac-help/add-and-customize-widgets-mchl52be5da5/mac" 25 | } 26 | var body: some View { 27 | Section { 28 | Link(destination: .init(string: Self.urlString)!) { 29 | Label("Add and customize widgets on Mac", systemImage: "link") 30 | } 31 | } header: { 32 | Text("Apple Support Page Link") 33 | } footer: { 34 | Text(Self.urlString) 35 | .font(.caption2) 36 | .foregroundStyle(.secondary) 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /watchOS/ContentView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct ContentView: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | var body: some View { 6 | NavigationStack { 7 | List { 8 | NavigationLink { 9 | 📚NotesListMenu() 10 | } label: { 11 | LabeledContent { 12 | Text(verbatim: "\(self.model.notes.count)") 13 | } label: { 14 | Label("Notes", systemImage: "books.vertical") 15 | } 16 | } 17 | NavigationLink { 18 | 🔩MainMenu() 19 | } label: { 20 | Label("Menu", systemImage: "gearshape") 21 | } 22 | NavigationLink { 23 | 💁GuideMenu() 24 | } label: { 25 | Label("Guide", systemImage: "star.bubble") 26 | } 27 | NavigationLink { 28 | ℹ️AboutAppMenu() 29 | } label: { 30 | Label("About App", systemImage: "questionmark") 31 | } 32 | } 33 | .navigationTitle("MemorizeWidget") 34 | } 35 | .onOpenURL(perform: self.model.handleWidgetURL) 36 | .modifier(📰SheetHandlerOnContentView()) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Shared/📗Note&Notes/📚Notes.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | typealias 📚Notes = [📗Note] 4 | 5 | extension 📚Notes { 6 | static func load() -> Self? { 7 | 💾ICloud.api.synchronize() 8 | return 💾ICloud.loadNotes() 9 | } 10 | } 11 | 12 | extension 📚Notes { 13 | mutating func cleanEmptyTitleNotes() { 14 | self.removeAll { $0.title.isEmpty } 15 | } 16 | func index(_ ⓘd: UUID?) -> Int? { 17 | self.firstIndex { $0.id == ⓘd } 18 | } 19 | } 20 | 21 | extension 📚Notes { 22 | func encode() -> Data { 23 | do { 24 | return try JSONEncoder().encode(self) 25 | } catch { 26 | assertionFailure(); return Data() 27 | } 28 | } 29 | static func decode(_ ⓓata: Data) -> Self { 30 | do { 31 | return try JSONDecoder().decode(Self.self, from: ⓓata) 32 | } catch { 33 | assertionFailure(); return [] 34 | } 35 | } 36 | var dataCount: Int { self.encode().count } 37 | var exceedDataSizePerhaps: Bool { self.dataCount > 800000 } 38 | } 39 | 40 | extension 📚Notes { 41 | static var placeholder: Self { 42 | [.init(.init(localized: "可愛い"), .init(localized: "cute, pretty, kawaii")), 43 | .init(.init(localized: "おやすみなさい"), .init(localized: "good night.")), 44 | .init(.init(localized: "苺"), .init(localized: "strawberry"))] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Shared/Rest/📣ADModel.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | enum 📣ADTargetApp: String, CaseIterable { 4 | case FlipByBlink 5 | case FadeInAlarm 6 | case PlainShogiBoard 7 | case TapWeight 8 | case TapTemperature 9 | case MemorizeWidget 10 | case LockInNote 11 | 12 | var localizationKey: LocalizedStringKey { .init(self.rawValue) } 13 | 14 | var url: URL { 15 | switch self { 16 | case .FlipByBlink: .init(string: "https://apps.apple.com/app/id1444571751")! 17 | case .FadeInAlarm: .init(string: "https://apps.apple.com/app/id1465336070")! 18 | case .PlainShogiBoard: .init(string: "https://apps.apple.com/app/id1620268476")! 19 | case .TapWeight: .init(string: "https://apps.apple.com/app/id1624159721")! 20 | case .TapTemperature: .init(string: "https://apps.apple.com/app/id1626760566")! 21 | case .MemorizeWidget: .init(string: "https://apps.apple.com/app/id1644276262")! 22 | case .LockInNote: .init(string: "https://apps.apple.com/app/id1644879340")! 23 | } 24 | } 25 | 26 | var mockImageName: String { "mock/" + self.rawValue } 27 | 28 | var iconImageName: String { "icon/" + self.rawValue } 29 | 30 | static func pickUpAppWithout(_ ⓜySelf: Self) -> Self { .allCases.filter({ $0 != ⓜySelf }).randomElement()! } 31 | 32 | var isHealthKitApp: Bool { [Self.TapTemperature, .TapWeight].contains(self) } 33 | } 34 | -------------------------------------------------------------------------------- /Shared/🎛️Option/🎛️Default.swift: -------------------------------------------------------------------------------- 1 | enum 🎛️Default { 2 | enum FontSize { 3 | enum SystemFamily { 4 | static let title = 24 5 | static let comment = 17 6 | } 7 | enum AccessoryFamily { 8 | static let title = 17 9 | static let comment = 13 10 | } 11 | } 12 | static func setValues() { 13 | if 💾UserDefaults.appGroup.bool(forKey: "setDefaultValues") == false { 14 | 💾UserDefaults.appGroup.set(Self.FontSize.SystemFamily.title, 15 | forKey: 🎛️Key.FontSize.SystemFamily.title) 16 | 💾UserDefaults.appGroup.set(Self.FontSize.SystemFamily.comment, 17 | forKey: 🎛️Key.FontSize.SystemFamily.comment) 18 | 💾UserDefaults.appGroup.set(Self.FontSize.AccessoryFamily.title, 19 | forKey: 🎛️Key.FontSize.AccessoryFamily.title) 20 | 💾UserDefaults.appGroup.set(Self.FontSize.AccessoryFamily.comment, 21 | forKey: 🎛️Key.FontSize.AccessoryFamily.comment) 22 | 💾UserDefaults.appGroup.set(true, forKey: "setDefaultValues") 23 | } 24 | } 25 | enum Search { 26 | static var openURLInOtherApp: Bool { 27 | #if os(iOS) 28 | false 29 | #elseif os(macOS) 30 | true 31 | #else 32 | false 33 | #endif 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /macOS/📚NotesWindow/🔦FocusedModel/FocusedValues(extension).swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension FocusedValues { 4 | var editingNote: Self.EditingNoteKey.Value? { 5 | get { self[Self.EditingNoteKey.self] } 6 | set { self[Self.EditingNoteKey.self] = newValue } 7 | } 8 | struct EditingNoteKey: FocusedValueKey { typealias Value = 📗Note } 9 | 10 | var notes: Self.NotesKey.Value? { 11 | get { self[Self.NotesKey.self] } 12 | set { self[Self.NotesKey.self] = newValue } 13 | } 14 | struct NotesKey: FocusedValueKey { typealias Value = 📚Notes } 15 | 16 | var notesSelection: Self.NotesSelectionKey.Value? { 17 | get { self[Self.NotesSelectionKey.self] } 18 | set { self[Self.NotesSelectionKey.self] = newValue } 19 | } 20 | struct NotesSelectionKey: FocusedValueKey { typealias Value = Set } 21 | 22 | var openedMainWindow: Self.OpenedMainWindow.Value? { 23 | get { self[Self.OpenedMainWindow.self] } 24 | set { self[Self.OpenedMainWindow.self] = newValue } 25 | } 26 | struct OpenedMainWindow: FocusedValueKey { typealias Value = Bool } 27 | 28 | var presentedSheetOnContentView: Self.PresentedSheetOnContentView.Value? { 29 | get { self[Self.PresentedSheetOnContentView.self] } 30 | set { self[Self.PresentedSheetOnContentView.self] = newValue } 31 | } 32 | struct PresentedSheetOnContentView: FocusedValueKey { typealias Value = 📰SheetOnContentView } 33 | } 34 | -------------------------------------------------------------------------------- /Shared/Rest/🚮DeleteAllNotesButton.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🚮DeleteAllNotesButton: View { 4 | #if os(iOS) || os(watchOS) 5 | @EnvironmentObject var model: 📱AppModel 6 | var body: some View { 7 | Button { 8 | self.model.presentedAllNotesDeleteConfirmDialog = true 9 | } label: { 10 | Label("Delete all notes", systemImage: "delete.backward.fill") 11 | } 12 | .listItemTint(self.model.notes.isEmpty ? nil : .red) 13 | .disabled(self.model.notes.isEmpty) 14 | } 15 | #elseif os(macOS) 16 | @FocusedObject var model: 📱AppModel? 17 | var body: some View { 18 | Button("Delete all notes") { 19 | self.model?.presentedAllNotesDeleteConfirmDialog = true 20 | } 21 | .disabled(self.model?.notes.isEmpty == true) 22 | } 23 | #endif 24 | } 25 | 26 | extension 🚮DeleteAllNotesButton { 27 | struct ConfirmDialog: ViewModifier { 28 | @EnvironmentObject var model: 📱AppModel 29 | func body(content: Content) -> some View { 30 | content 31 | .confirmationDialog("Delete all notes", 32 | isPresented: self.$model.presentedAllNotesDeleteConfirmDialog) { 33 | Button("OK, delete all notes.", role: .destructive) { 34 | withAnimation { 35 | self.model.removeAllNotes() 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Shared/📗Note&Notes/📚TextConvert.swift: -------------------------------------------------------------------------------- 1 | enum 📚TextConvert { 2 | enum Separator: String { 3 | case tab = "\t" 4 | case comma = "," 5 | case titleOnly = "" 6 | } 7 | static func decode(_ ⓘnputText: String, _ ⓢeparator: Self.Separator) -> 📚Notes { 8 | var ⓥalue: 📚Notes = [] 9 | let ⓞneLineTexts: [String] = ⓘnputText.components(separatedBy: .newlines) 10 | ⓞneLineTexts.forEach { ⓞneLine in 11 | if !ⓞneLine.isEmpty { 12 | if ⓢeparator == .titleOnly { 13 | ⓥalue.append(📗Note(ⓞneLine)) 14 | } else { 15 | let ⓣexts = ⓞneLine.components(separatedBy: ⓢeparator.rawValue) 16 | if let ⓣitle = ⓣexts.first { 17 | if !ⓣitle.isEmpty { 18 | let ⓒomment = ⓞneLine.dropFirst(ⓣitle.count + 1).description 19 | ⓥalue.append(📗Note(ⓣitle, ⓒomment)) 20 | } 21 | } 22 | } 23 | } 24 | } 25 | return ⓥalue 26 | } 27 | static func encodeToTSV(_ ⓝotes: 📚Notes) -> String { 28 | ⓝotes.reduce(into: "") { ⓟartialResult, ⓝote in 29 | var ⓣempNote = ⓝote 30 | ⓣempNote.title.removeAll(where: { $0 == "\n" }) 31 | ⓣempNote.comment.removeAll(where: { $0 == "\n" }) 32 | ⓟartialResult += ⓣempNote.title + "\t" + ⓣempNote.comment 33 | if ⓝote != ⓝotes.last { ⓟartialResult += "\n" } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /iOS/📖WidgetSheet/📖SingleNoteLayoutView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📖SingleNoteLayoutView: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | var body: some View { 6 | VStack { 7 | Spacer() 8 | if let ⓘndex = self.model.openedWidgetSingleNoteIndex { 9 | 📗NoteView(source: self.$model.notes[ⓘndex], 10 | titleFont: .largeTitle, 11 | commentFont: .title, 12 | placement: .widgetSheet) 13 | .padding(.horizontal, 32) 14 | Spacer() 15 | HStack { 16 | Spacer() 17 | 📖DictionaryButton(self.model.notes[ⓘndex]) 18 | Spacer() 19 | 📖SearchButton(self.model.notes[ⓘndex]) 20 | Spacer() 21 | if !self.model.randomMode { 22 | 📖MoveEndButton(self.model.notes[ⓘndex]) 23 | Spacer() 24 | } 25 | 🚮DeleteNoteButton(self.model.notes[ⓘndex]) 26 | Spacer() 27 | } 28 | .labelStyle(.iconOnly) 29 | .buttonStyle(.plain) 30 | .foregroundColor(.primary) 31 | .font(.title) 32 | .padding(.horizontal, 24) 33 | } else { 34 | 📖DeletedNoteView() 35 | .padding(.bottom, 24) 36 | } 37 | Spacer() 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /macOS/📱AppModel(extension).swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension 📱AppModel { 4 | func clearSelection() { 5 | self.notesSelection.removeAll() 6 | } 7 | func removeNotesByDeleteCommand() { 8 | let ⓣargetNotes = self.notes.filter { self.notesSelection.contains($0.id) } 9 | self.trash.storeDeletedNotes(ⓣargetNotes) 10 | self.notes.removeAll { ⓣargetNotes.contains($0) } 11 | self.saveNotes() 12 | self.clearSelection() 13 | } 14 | func insertAbove(_ ⓣargetNotes: Set<📗Note>) { 15 | if let ⓝote = ⓣargetNotes.first, 16 | let ⓘndex = self.notes.firstIndex(of: ⓝote) { 17 | self.clearSelection() 18 | self.addNewNote(index: ⓘndex) 19 | } 20 | } 21 | func insertBelow(_ ⓣargetNotes: Set<📗Note>) { 22 | if let ⓝote = ⓣargetNotes.first, 23 | let ⓘndex = self.notes.firstIndex(of: ⓝote) { 24 | self.clearSelection() 25 | self.addNewNote(index: ⓘndex + 1) 26 | } 27 | } 28 | func moveTop(_ ⓝotes: Set<📗Note>) { 29 | self.notes.move(fromOffsets: .init(ⓝotes.compactMap { self.notes.firstIndex(of: $0) }), 30 | toOffset: 0) 31 | self.saveNotes() 32 | self.clearSelection() 33 | } 34 | func moveEnd(_ ⓝotes: Set<📗Note>) { 35 | self.notes.move(fromOffsets: .init(ⓝotes.compactMap { self.notes.firstIndex(of: $0) }), 36 | toOffset: self.notes.endIndex) 37 | self.saveNotes() 38 | self.clearSelection() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /MemorizeWidget.xcodeproj/xcuserdata/account2309.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ShareExtension(iOS).xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 2 11 | 12 | Widget(iOS).xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | Widget(macOS).xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 6 21 | 22 | Widget(watchOS).xcscheme_^#shared#^_ 23 | 24 | orderHint 25 | 4 26 | 27 | iOS.xcscheme_^#shared#^_ 28 | 29 | orderHint 30 | 0 31 | 32 | macOS.xcscheme_^#shared#^_ 33 | 34 | orderHint 35 | 5 36 | 37 | watchOS.xcscheme_^#shared#^_ 38 | 39 | orderHint 40 | 3 41 | 42 | 43 | SuppressBuildableAutocreation 44 | 45 | 16C3D76E2B0968B900849D96 46 | 47 | primary 48 | 49 | 50 | 16C3D7C52B0989F400849D96 51 | 52 | primary 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Shared/🪧Widget/🪧PrimaryWidget.swift: -------------------------------------------------------------------------------- 1 | import WidgetKit 2 | import SwiftUI 3 | 4 | struct 🪧PrimaryWidget: Widget { 5 | var body: some WidgetConfiguration { 6 | StaticConfiguration(kind: Self.kind, provider: 🪧Provider(kind: .primary)) { 7 | 🪧EntryView($0) 8 | } 9 | .configurationDisplayName(Self.configurationDisplayName) 10 | .description("Show a note.") 11 | .supportedFamilies(Self.supportedFamilies) 12 | #if os(iOS) || os(macOS) 13 | .contentMarginsDisabled() 14 | #endif 15 | } 16 | } 17 | 18 | private extension 🪧PrimaryWidget { 19 | private static var kind: String { 20 | #if os(iOS) 21 | "main" 22 | #elseif os(watchOS) 23 | "MWComplication" 24 | #elseif os(macOS) 25 | "primary" 26 | #endif 27 | } 28 | private static var configurationDisplayName: LocalizedStringKey { 29 | #if os(iOS) || os(macOS) 30 | "MemorizeWidget" 31 | #elseif os(watchOS) 32 | "Notes" 33 | #endif 34 | } 35 | private static var supportedFamilies: [WidgetFamily] { 36 | #if os(iOS) 37 | [.systemSmall, .systemMedium, .systemLarge, .systemExtraLarge, 38 | .accessoryInline, .accessoryRectangular, .accessoryCircular] 39 | #elseif os(watchOS) 40 | [.accessoryInline, .accessoryRectangular, .accessoryCircular, .accessoryCorner] 41 | #elseif os(macOS) 42 | if #available(macOS 14.0, *) { 43 | [.systemSmall, .systemMedium, .systemLarge, .systemExtraLarge] 44 | } else { 45 | [.systemSmall, .systemMedium, .systemLarge] 46 | } 47 | #endif 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /iOS/🔖Tab&Sidebar/🔖Sidebar.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | enum 🔖Sidebar { 4 | case notesList 5 | case option 6 | case trash 7 | case guide 8 | } 9 | 10 | extension 🔖Sidebar: CaseIterable, Identifiable { 11 | var id: Self { self } 12 | func navigationLink() -> some View { 13 | NavigationLink(value: self) { 14 | Label(self.title, systemImage: self.iconName) 15 | } 16 | //よく分からないがサンプルコードではNavigationLinkで実装してる例あり。 17 | //Label(self.title, systemImage: self.iconName) ← これとの差異がよく分からない。 18 | } 19 | func detailView() -> some View { 20 | Self.DetailView(selection: self) 21 | } 22 | } 23 | 24 | private extension 🔖Sidebar { 25 | private var title: LocalizedStringKey { 26 | switch self { 27 | case .notesList: "Notes" 28 | case .option: "Option" 29 | case .trash: "Trash" 30 | case .guide: "Guide" 31 | } 32 | } 33 | private var iconName: String { 34 | switch self { 35 | case .notesList: "text.justify.leading" 36 | case .option: "gearshape" 37 | case .trash: "trash" 38 | case .guide: "questionmark" 39 | } 40 | } 41 | private struct DetailView: View { 42 | var selection: 🔖Sidebar 43 | var body: some View { 44 | switch self.selection { 45 | case .notesList: 📚NotesListTab() 46 | case .option: 🎛️OptionTab() 47 | case .trash: 🗑TrashTab() 48 | case .guide: 💁GuideTab() 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /macOS/Supporting files/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "macOS16.png", 5 | "idiom" : "mac", 6 | "scale" : "1x", 7 | "size" : "16x16" 8 | }, 9 | { 10 | "filename" : "macOS32 1.png", 11 | "idiom" : "mac", 12 | "scale" : "2x", 13 | "size" : "16x16" 14 | }, 15 | { 16 | "filename" : "macOS32.png", 17 | "idiom" : "mac", 18 | "scale" : "1x", 19 | "size" : "32x32" 20 | }, 21 | { 22 | "filename" : "macOS64.png", 23 | "idiom" : "mac", 24 | "scale" : "2x", 25 | "size" : "32x32" 26 | }, 27 | { 28 | "filename" : "macOS128.png", 29 | "idiom" : "mac", 30 | "scale" : "1x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "filename" : "macOS256 1.png", 35 | "idiom" : "mac", 36 | "scale" : "2x", 37 | "size" : "128x128" 38 | }, 39 | { 40 | "filename" : "macOS256.png", 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "256x256" 44 | }, 45 | { 46 | "filename" : "macOS512 1.png", 47 | "idiom" : "mac", 48 | "scale" : "2x", 49 | "size" : "256x256" 50 | }, 51 | { 52 | "filename" : "macOS512.png", 53 | "idiom" : "mac", 54 | "scale" : "1x", 55 | "size" : "512x512" 56 | }, 57 | { 58 | "filename" : "macOS1024.png", 59 | "idiom" : "mac", 60 | "scale" : "2x", 61 | "size" : "512x512" 62 | } 63 | ], 64 | "info" : { 65 | "author" : "xcode", 66 | "version" : 1 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /macOS/App Extensions/Widget/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "macOS16.png", 5 | "idiom" : "mac", 6 | "scale" : "1x", 7 | "size" : "16x16" 8 | }, 9 | { 10 | "filename" : "macOS32 1.png", 11 | "idiom" : "mac", 12 | "scale" : "2x", 13 | "size" : "16x16" 14 | }, 15 | { 16 | "filename" : "macOS32.png", 17 | "idiom" : "mac", 18 | "scale" : "1x", 19 | "size" : "32x32" 20 | }, 21 | { 22 | "filename" : "macOS64.png", 23 | "idiom" : "mac", 24 | "scale" : "2x", 25 | "size" : "32x32" 26 | }, 27 | { 28 | "filename" : "macOS128.png", 29 | "idiom" : "mac", 30 | "scale" : "1x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "filename" : "macOS256 1.png", 35 | "idiom" : "mac", 36 | "scale" : "2x", 37 | "size" : "128x128" 38 | }, 39 | { 40 | "filename" : "macOS256.png", 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "256x256" 44 | }, 45 | { 46 | "filename" : "macOS512 1.png", 47 | "idiom" : "mac", 48 | "scale" : "2x", 49 | "size" : "256x256" 50 | }, 51 | { 52 | "filename" : "macOS512.png", 53 | "idiom" : "mac", 54 | "scale" : "1x", 55 | "size" : "512x512" 56 | }, 57 | { 58 | "filename" : "macOS1024.png", 59 | "idiom" : "mac", 60 | "scale" : "2x", 61 | "size" : "512x512" 62 | } 63 | ], 64 | "info" : { 65 | "author" : "xcode", 66 | "version" : 1 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /macOS/Supporting files/🌐Localization/InfoPlist.xcstrings: -------------------------------------------------------------------------------- 1 | { 2 | "sourceLanguage" : "en", 3 | "strings" : { 4 | "CFBundleDisplayName" : { 5 | "comment" : "Bundle display name", 6 | "extractionState" : "extracted_with_value", 7 | "localizations" : { 8 | "en" : { 9 | "stringUnit" : { 10 | "state" : "new", 11 | "value" : "MemorizeWidget" 12 | } 13 | }, 14 | "ja" : { 15 | "stringUnit" : { 16 | "state" : "translated", 17 | "value" : "暗記ウィジェット" 18 | } 19 | } 20 | } 21 | }, 22 | "CFBundleName" : { 23 | "comment" : "Bundle name", 24 | "extractionState" : "extracted_with_value", 25 | "localizations" : { 26 | "en" : { 27 | "stringUnit" : { 28 | "state" : "new", 29 | "value" : "MemorizeWidget" 30 | } 31 | }, 32 | "ja" : { 33 | "stringUnit" : { 34 | "state" : "translated", 35 | "value" : "暗記ウィジェット" 36 | } 37 | } 38 | } 39 | }, 40 | "NSHumanReadableCopyright" : { 41 | "comment" : "Copyright (human-readable)", 42 | "extractionState" : "extracted_with_value", 43 | "localizations" : { 44 | "en" : { 45 | "stringUnit" : { 46 | "state" : "new", 47 | "value" : "Ryo Yamashita" 48 | } 49 | }, 50 | "ja" : { 51 | "stringUnit" : { 52 | "state" : "translated", 53 | "value" : "" 54 | } 55 | } 56 | } 57 | } 58 | }, 59 | "version" : "1.0" 60 | } -------------------------------------------------------------------------------- /iOS/🔖Tab&Sidebar/🔖Tab.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | enum 🔖Tab { 4 | case notesList 5 | case option 6 | case trash 7 | case guide 8 | case app 9 | } 10 | 11 | extension 🔖Tab: CaseIterable, Identifiable { 12 | var id: Self { self } 13 | func label() -> some View { 14 | Label(self.title, systemImage: self.iconName) 15 | } 16 | func detailView() -> some View { 17 | Self.DetailView(selection: self) 18 | } 19 | } 20 | 21 | private extension 🔖Tab { 22 | private var title: LocalizedStringKey { 23 | switch self { 24 | case .notesList: "Notes" 25 | case .option: "Option" 26 | case .trash: "Trash" 27 | case .guide: "Guide" 28 | case .app: "App" 29 | } 30 | } 31 | private var iconName: String { 32 | switch self { 33 | case .notesList: "text.justify.leading" 34 | case .option: "gearshape" 35 | case .trash: "trash" 36 | case .guide: "questionmark" 37 | case .app: "info" 38 | } 39 | } 40 | private struct DetailView: View { 41 | var selection: 🔖Tab 42 | var body: some View { 43 | Group { 44 | switch self.selection { 45 | case .notesList: 📚NotesListTab() 46 | case .option: 🎛️OptionTab() 47 | case .trash: 🗑TrashTab() 48 | case .guide: 💁GuideTab() 49 | case .app: ℹ️AboutAppTab() 50 | } 51 | } 52 | .tag(self.selection) 53 | .tabItem(self.selection.label) 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Shared/🎛️Option/🎛️MultilineTextAlignment.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | enum 🎛️MultilineTextAlignment: String { 4 | case leading, center, trailing 5 | } 6 | 7 | extension 🎛️MultilineTextAlignment: CaseIterable, Identifiable { 8 | var id: Self { self } 9 | static func loadUserDeaults() -> Self { 10 | if let ⓢtring = 💾UserDefaults.appGroup.string(forKey: 🎛️Key.multilineTextAlignment), 11 | let ⓥalue = Self(rawValue: ⓢtring) { 12 | ⓥalue 13 | } else { 14 | .center 15 | } 16 | } 17 | var localizedTitle: LocalizedStringKey { 18 | switch self { 19 | case .leading: "leading" 20 | case .center: "center" 21 | case .trailing: "trailing" 22 | } 23 | } 24 | var iconName: String { 25 | switch self { 26 | case .leading: "text.justify.leading" 27 | case .center: "text.aligncenter" 28 | case .trailing: "text.justify.trailing" 29 | } 30 | } 31 | func value() -> TextAlignment { 32 | if 🎛️Option.multiNotesMode { 33 | .center 34 | } else { 35 | switch self { 36 | case .leading: .leading 37 | case .center: .center 38 | case .trailing: .trailing 39 | } 40 | } 41 | } 42 | func value() -> HorizontalAlignment { 43 | if 🎛️Option.multiNotesMode { 44 | .center 45 | } else { 46 | switch self { 47 | case .leading: .leading 48 | case .center: .center 49 | case .trailing: .trailing 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /iOS/Supporting files/🌐Localization/🌐AppStoreDescription.xcstrings: -------------------------------------------------------------------------------- 1 | { 2 | "sourceLanguage" : "en", 3 | "strings" : { 4 | "current" : { 5 | "localizations" : { 6 | "en" : { 7 | "stringUnit" : { 8 | "state" : "translated", 9 | "value" : "Flashcard on widget. Memorize notes in everyday life.\n\nYou create freely notes for widget.\n\nApp presents the notes on widget.\n\n\nOption\n\n- Random mode: widget changes the note per 5 minutes.\n\n- Show multi notes.\n\n- Show comment on widget.\n\n- Font size on widget.\n\n\nRest\n\n- Import file(e.g. tsv, csv, txt) or text.\n\n- System dictionary support.\n\n- Customizable search function.\n\n- Sync between devices by iCloud.\n\n\nMulti platform support\n\niPhone: Home screen, Lock screen, StandBy(iOS 17)\n\niPad: Home screen, Lock screen(iPadOS 17)\n\nMac: Notification center, Desktop(macOS 14)\n\nApple Watch: Complication, Smart Stack(watchOS 10)" 10 | } 11 | }, 12 | "ja" : { 13 | "stringUnit" : { 14 | "state" : "translated", 15 | "value" : "ウィジェット機能を用いてホーム画面やロック画面などに暗記帳を表示します。\n\n日常の中で暗記帳をたくさんチラ見して知識を脳に染み込ませるためのアプリです。\n\n自由にノートを作成できます。\n\nそのノートはウィジェット上にシンプルに表示されます。\n\n\nオプション\n\n・ランダムモード: このモードでは5分毎にウィジェット上のノートをランダムに更新\n\n・ウィジェット上で複数個のノートを表示\n\n・ウィジェット上でノートの「コメント」を表示\n\n・ウィジェット上のフォントのサイズを変更\n\n\nその他\n\n・テキストやファイル(csv、tsv、txtなど)から暗記帳データをインポート可能\n\n・OS内蔵の辞書と連携\n\n・カスタマイズ可能な検索機能\n\n・iCloudによって端末間でデータを同期\n\n\nマルチプラットフォーム対応\n\niPhone : ホーム画面、ロック画面、スタンバイ(iOS 17)\n\niPad : ホーム画面、ロック画面(iPadOS 17)\n\nMac : 通知センター、デスクトップ(macOS 14)\n\nApple Watch : コンプリケーション、スマートスタック(watchOS 10)" 16 | } 17 | } 18 | } 19 | } 20 | }, 21 | "version" : "1.0" 22 | } -------------------------------------------------------------------------------- /macOS/Supporting files/🌐Localization/🌐AppStoreDescription.xcstrings: -------------------------------------------------------------------------------- 1 | { 2 | "sourceLanguage" : "en", 3 | "strings" : { 4 | "current" : { 5 | "localizations" : { 6 | "en" : { 7 | "stringUnit" : { 8 | "state" : "translated", 9 | "value" : "Flashcard on widget. Memorize notes in everyday life.\n\nYou create freely notes for widget.\n\nApp presents the notes on widget.\n\n\nOption\n\n- Random mode: widget changes the note per 5 minutes.\n\n- Show multi notes.\n\n- Show comment on widget.\n\n- Font size on widget.\n\n\nRest\n\n- Import file(e.g. tsv, csv, txt) or text.\n\n- System dictionary support.\n\n- Customizable search function.\n\n- Sync between devices by iCloud.\n\n\nMulti platform support\n\niPhone: Home screen, Lock screen, StandBy(iOS 17)\n\niPad: Home screen, Lock screen(iPadOS 17)\n\nMac: Notification center, Desktop(macOS 14)\n\nApple Watch: Complication, Smart Stack(watchOS 10)" 10 | } 11 | }, 12 | "ja" : { 13 | "stringUnit" : { 14 | "state" : "translated", 15 | "value" : "ウィジェット機能を用いてホーム画面やロック画面などに暗記帳を表示します。\n\n日常の中で暗記帳をたくさんチラ見して知識を脳に染み込ませるためのアプリです。\n\n自由にノートを作成できます。\n\nそのノートはウィジェット上にシンプルに表示されます。\n\n\nオプション\n\n・ランダムモード: このモードでは5分毎にウィジェット上のノートをランダムに更新\n\n・ウィジェット上で複数個のノートを表示\n\n・ウィジェット上でノートの「コメント」を表示\n\n・ウィジェット上のフォントのサイズを変更\n\n\nその他\n\n・テキストやファイル(csv、tsv、txtなど)から暗記帳データをインポート可能\n\n・OS内蔵の辞書と連携\n\n・カスタマイズ可能な検索機能\n\n・iCloudによって端末間でデータを同期\n\n\nマルチプラットフォーム対応\n\niPhone : ホーム画面、ロック画面、スタンバイ(iOS 17)\n\niPad : ホーム画面、ロック画面(iPadOS 17)\n\nMac : 通知センター、デスクトップ(macOS 14)\n\nApple Watch : コンプリケーション、スマートスタック(watchOS 10)" 16 | } 17 | } 18 | } 19 | } 20 | }, 21 | "version" : "1.0" 22 | } -------------------------------------------------------------------------------- /Shared/🪧Widget/Rest/🪧PlaceholderView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🪧PlaceholderView: View { 4 | @Environment(\.widgetFamily) var widgetFamily 5 | var body: some View { 6 | switch self.widgetFamily { 7 | #if os(iOS) || os(watchOS) 8 | case .accessoryInline, .accessoryCircular: 9 | Text(verbatim: "Placeholder") 10 | #endif 11 | #if os(watchOS) 12 | case .accessoryCorner: 13 | Image(systemName: "tag") 14 | .widgetLabel("Placeholder" as String) 15 | #endif 16 | default: 17 | VStack(spacing: 2) { 18 | Text(verbatim: "Placeholder") 19 | .font(.system(size: self.titleFontSize)) 20 | Text(verbatim: "Placeholder") 21 | .font(.system(size: self.commentFontSize)) 22 | .foregroundStyle(.secondary) 23 | } 24 | } 25 | } 26 | } 27 | 28 | private extension 🪧PlaceholderView { 29 | private var titleFontSize: CGFloat { 30 | switch self.widgetFamily { 31 | case .accessoryRectangular: 20 32 | case .systemSmall: 23 33 | case .systemMedium: 30 34 | case .systemLarge: 40 35 | case .systemExtraLarge: 50 36 | default: 23 37 | } 38 | } 39 | private var commentFontSize: CGFloat { 40 | switch self.widgetFamily { 41 | case .accessoryRectangular: 14 42 | case .systemSmall: 16 43 | case .systemMedium: 20 44 | case .systemLarge: 23 45 | case .systemExtraLarge: 24 46 | default: 14 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Shared/🗑Trash/🗑TrashModel.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🗑TrashModel: Codable { 4 | private(set) var deletedContents: 🗑DeletedContents 5 | } 6 | 7 | extension 🗑TrashModel { 8 | static var empty: Self { .init(deletedContents: []) } 9 | mutating func storeDeletedNotes(_ ⓝotes: 📚Notes) { 10 | let ⓓeletedNotes = ⓝotes.filter { !$0.isEmpty } 11 | guard !ⓓeletedNotes.isEmpty else { return } 12 | let ⓒontent = 🗑DeletedContent(date: .now, notes: ⓓeletedNotes) 13 | self.deletedContents.insert(ⓒontent, at: 0) 14 | self.save() 15 | } 16 | mutating func remove(_ ⓒontent: 🗑DeletedContent) { 17 | self.deletedContents.removeAll { $0 == ⓒontent } 18 | self.save() 19 | } 20 | mutating func clearDeletedContents() { 21 | self.deletedContents.removeAll() 22 | self.save() 23 | 💥Feedback.warning() 24 | } 25 | mutating func cleanExceededContents() { 26 | self.deletedContents.forEach { ⓒontent in 27 | if ⓒontent.date.distance(to: .now) > (60 * 60 * 24 * 7) { 28 | self.remove(ⓒontent) 29 | } 30 | } 31 | } 32 | static func load() -> Self { 33 | guard let ⓓata = 💾UserDefaults.appGroup.data(forKey: "DeletedContents") else { return .empty } 34 | guard let ⓜodel = try? JSONDecoder().decode(Self.self, from: ⓓata) else { assertionFailure(); return .empty } 35 | return ⓜodel 36 | } 37 | } 38 | 39 | private extension 🗑TrashModel { 40 | private func save() { 41 | guard let ⓓata = try? JSONEncoder().encode(self) else { assertionFailure(); return } 42 | 💾UserDefaults.appGroup.set(ⓓata, forKey: "DeletedContents") 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /macOS/📥NotesImport/📥NotesImportFileSheetView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📥NotesImportFileSheetView: View { 4 | @StateObject private var model: 📥NotesImportModel = .init() 5 | var body: some View { 6 | NavigationStack(path: self.$model.navigationPath) { 7 | Form { 8 | 📥SeparatorPicker() 9 | 📥NotSupportMultiLineTextInNoteSection() 10 | } 11 | .formStyle(.grouped) 12 | .toolbar { 13 | 📥DismissButton() 14 | ToolbarItem(placement: .primaryAction) { 15 | if self.model.navigationPath.isEmpty { 16 | Button { 17 | self.model.showFileImporter.toggle() 18 | } label: { 19 | Label("Import a text-encoded file", systemImage: "folder.badge.plus") 20 | } 21 | } 22 | } 23 | } 24 | .environmentObject(self.model) 25 | .navigationDestination(for: String.self) { 26 | 📥ConvertedNotesMenu(importedText: $0) 27 | .environmentObject(self.model) 28 | } 29 | .navigationTitle("Import notes") 30 | .fileImporter(isPresented: self.$model.showFileImporter, allowedContentTypes: [.text]) { 31 | self.model.fileImporterAction($0) 32 | } 33 | .alert("⚠️ Error", isPresented: self.$model.alertError) { 34 | Button("OK") { self.model.caughtError = nil } 35 | } message: { 36 | self.model.caughtError?.messageText() 37 | } 38 | } 39 | .frame(width: 400, height: 360) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Shared/🪧Widget/Rest/🪧NoNoteView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🪧NoNoteView: View { 4 | @Environment(\.widgetFamily) var widgetFamily 5 | @Environment(\.showsWidgetContainerBackground) var showsWidgetContainerBackground 6 | var body: some View { 7 | switch self.widgetFamily { 8 | case .systemSmall: 9 | Label("No note", systemImage: "book.closed") 10 | .font(.title2) 11 | .foregroundStyle(self.showsWidgetContainerBackground ? .tertiary : .secondary) 12 | .padding(8) 13 | case .systemMedium: 14 | Label("No note", systemImage: "book.closed") 15 | .font(.title) 16 | .foregroundStyle(.tertiary) 17 | .padding() 18 | case .systemLarge, .systemExtraLarge: 19 | Label("No note", systemImage: "book.closed") 20 | .font(.largeTitle) 21 | .foregroundStyle(.tertiary) 22 | .padding() 23 | case .accessoryRectangular: 24 | Label("No note", systemImage: "book.closed") 25 | .font(.headline) 26 | .foregroundStyle(.secondary) 27 | case .accessoryCircular: 28 | Text("No note") 29 | .font(.subheadline.weight(.semibold)) 30 | .foregroundStyle(.secondary) 31 | case .accessoryInline: 32 | Label("No note", systemImage: "book.closed") 33 | #if os(watchOS) 34 | case .accessoryCorner: 35 | Label("No note", systemImage: "book.closed") 36 | #endif 37 | default: 38 | Image(systemName: "book.closed") 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Shared/🎛️Option/🎛️RandomModeToggle.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import WidgetKit 3 | 4 | struct 🎛️RandomModeToggle: View { 5 | @EnvironmentObject var model: 📱AppModel 6 | @Environment(\.horizontalSizeClass) var horizontalSizeClass 7 | var body: some View { 8 | Toggle(isOn: self.$model.randomMode) { 9 | #if os(iOS) 10 | if UIDevice.current.userInterfaceIdiom == .pad { 11 | self.labelForIPad() 12 | } else { 13 | Self.label() 14 | } 15 | #else 16 | Self.label() 17 | #endif 18 | } 19 | .onChange(of: self.model.randomMode) { _ in 20 | WidgetCenter.shared.reloadAllTimelines() 21 | } 22 | #if os(iOS) 23 | .modifier(📚DisableInEditMode()) 24 | #endif 25 | } 26 | struct Caption: View { 27 | var body: some View { 28 | Text("Change the note per 5 minutes.") 29 | } 30 | } 31 | } 32 | 33 | private extension 🎛️RandomModeToggle { 34 | private static func label() -> some View { 35 | Label("Random mode", systemImage: "shuffle") 36 | } 37 | private func labelForIPad() -> some View { 38 | #if os(iOS) 39 | Group { 40 | switch self.horizontalSizeClass { 41 | case .compact: 42 | Self.label() 43 | default: 44 | LabeledContent { 45 | Text("Per 5 minutes") 46 | .font(.caption.weight(.light)) 47 | .padding(.trailing, 8) 48 | .accessibilityLabel(Text(verbatim: "")) 49 | } label: { 50 | Self.label() 51 | } 52 | } 53 | } 54 | #else 55 | EmptyView() 56 | #endif 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /iOS/🔖Tab&Sidebar/🔖SplitView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🔖SplitView: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | var body: some View { 6 | NavigationSplitView { 7 | List(selection: self.$model.selectedSidebar) { 8 | ForEach(🔖Sidebar.allCases) { $0.navigationLink() } 9 | } 10 | .background(ignoresSafeAreaEdges: .all) 11 | .navigationSplitViewColumnWidth(280) //default: 320 12 | .environment(\.defaultMinListRowHeight, 50) 13 | .navigationBarTitleDisplayMode(.inline) 14 | .toolbar(.visible, for: .navigationBar) 15 | .toolbar { self.bottomBarButtons() } 16 | } detail: { 17 | if let ⓢelectedSidebar = self.model.selectedSidebar { 18 | ⓢelectedSidebar.detailView() 19 | } else { 20 | Self.placeholderView() 21 | } 22 | } 23 | .navigationSplitViewStyle(.balanced) 24 | } 25 | } 26 | 27 | private extension 🔖SplitView { 28 | private func bottomBarButtons() -> some ToolbarContent { 29 | ToolbarItemGroup(placement: .bottomBar) { 30 | Button { 31 | self.model.presentSheetOnContentView(.aboutApp) 32 | } label: { 33 | Label("App", systemImage: "info.circle") 34 | } 35 | Spacer() 36 | Button { 37 | self.model.presentSheetOnContentView(.purchase) 38 | } label: { 39 | Label("Purchase", systemImage: "cart") 40 | } 41 | } 42 | } 43 | private static func placeholderView() -> some View { 44 | Label("Select sidebar", systemImage: "arrowshape.left") 45 | .font(.title) 46 | .foregroundStyle(.tertiary) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /watchOS/📚NotesListMenu.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📚NotesListMenu: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | var body: some View { 6 | List { 7 | self.newNoteButton() 8 | ForEach(self.$model.notes) { ⓝote in 9 | NavigationLink { 10 | 📗NoteView(ⓝote, .notesMenu) 11 | } label: { 12 | Self.NoteLinkLabel(target: ⓝote) 13 | } 14 | } 15 | .onMove { 16 | self.model.moveNoteForDynamicView($0, $1) 17 | 💥Feedback.light() 18 | } 19 | .onDelete(perform: self.model.deleteNotesForDynamicView) 20 | } 21 | .animation(.default, value: self.model.notes) 22 | .navigationTitle("Notes") 23 | } 24 | } 25 | 26 | private extension 📚NotesListMenu { 27 | private func newNoteButton() -> some View { 28 | TextFieldLink { 29 | Label("New note", systemImage: "plus") 30 | } onSubmit: { 31 | self.model.insertOnTop([.init($0)]) 32 | } 33 | } 34 | private struct NoteLinkLabel: View { 35 | @EnvironmentObject var model: 📱AppModel 36 | @Binding var target: 📗Note 37 | private var inactive: Bool { 38 | !self.model.randomMode 39 | && 40 | self.target != self.model.notes.first 41 | } 42 | var body: some View { 43 | VStack(alignment: .leading) { 44 | Text(self.target.title) 45 | .font(.headline) 46 | .foregroundStyle(self.inactive ? .secondary : .primary) 47 | Text(self.target.comment) 48 | .font(.caption) 49 | .foregroundStyle(.secondary) 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Shared/🗑Trash/🗑TrashViewComponent.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | enum 🗑TrashViewComponent { 4 | struct DateText: View { 5 | var source: 🗑DeletedContent 6 | var body: some View { 7 | Text(self.source.date, style: .offset) 8 | + 9 | Text(verbatim: " (\(self.source.date.formatted(.dateTime.month().day().hour().minute())))") 10 | } 11 | } 12 | struct RestoreButton: View { 13 | @EnvironmentObject var model: 📱AppModel 14 | var source: 🗑DeletedContent 15 | var body: some View { 16 | Button { 17 | self.model.restore(self.source) 18 | } label: { 19 | Label("Restore \(self.source.notes.count) notes", 20 | systemImage: "arrow.uturn.backward.circle.fill") 21 | } 22 | .accessibilityLabel("Restore") 23 | } 24 | } 25 | struct ClearButton: View { 26 | @EnvironmentObject var model: 📱AppModel 27 | var body: some View { 28 | Button(role: .destructive) { 29 | self.model.trash.clearDeletedContents() 30 | } label: { 31 | Label("Clear trash", systemImage: "trash.slash") 32 | } 33 | .tint(.red) 34 | .disabled(self.model.trash.deletedContents.isEmpty) 35 | } 36 | } 37 | struct AboutSection: View { 38 | var body: some View { 39 | Section { 40 | Label("After 7 days, the notes will be permanently deleted.", 41 | systemImage: "clock.badge.exclamationmark") 42 | Label("Trash do not sync with iCloud.", systemImage: "xmark.icloud") 43 | } 44 | .font(.subheadline) 45 | .foregroundStyle(.secondary) 46 | .listRowBackground(Color.clear) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Shared/🪧Widget/🪧EntryView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 🪧EntryView: View { 4 | private var entry: 🪧Entry 5 | @Environment(\.widgetFamily) var widgetFamily 6 | var body: some View { 7 | Group { 8 | switch self.entry.phase { 9 | case .placeholder: 10 | 🪧PlaceholderView() 11 | case .snapshot, .inTimeline: 12 | if self.entry.pickedNotes.isEmpty { 13 | 🪧NoNoteView() 14 | } else { 15 | #if os(iOS) 16 | switch self.widgetFamily { 17 | case .systemSmall, .systemMedium, .systemLarge, .systemExtraLarge: 18 | 🪧SystemWidgetView(notes: self.entry.pickedNotes) 19 | case .accessoryInline, .accessoryCircular, .accessoryRectangular: 20 | 🪧AccessoryWidgetView(notes: self.entry.pickedNotes) 21 | default: 22 | Text(verbatim: "BUG") 23 | } 24 | #elseif os(watchOS) 25 | 🪧AccessoryWidgetView(notes: self.entry.pickedNotes) 26 | #elseif os(macOS) 27 | 🪧SystemWidgetView(notes: self.entry.pickedNotes) 28 | #endif 29 | } 30 | } 31 | } 32 | .widgetURL(self.tag.encode()) 33 | .modifier(🪧ContainerBackground()) 34 | } 35 | init(_ entry: 🪧Entry) { 36 | self.entry = entry 37 | } 38 | } 39 | 40 | private extension 🪧EntryView { 41 | private var tag: 🪧Tag { 42 | switch self.entry.phase { 43 | case .placeholder: 44 | .placeholder 45 | case .snapshot, .inTimeline: 46 | .notes(self.entry.pickedNotes.map(\.id)) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /macOS/Rest/📤NotesExportSheetView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📤NotesExportSheetView: View { 4 | @EnvironmentObject var model: 📱AppModel 5 | @State private var ⓒonvertedText: String? 6 | var body: some View { 7 | NavigationStack { 8 | Group { 9 | if let ⓒonvertedText { 10 | Self.exampleView(ⓒonvertedText) 11 | } else { 12 | ZStack { 13 | Color.clear 14 | ProgressView() 15 | } 16 | } 17 | } 18 | .navigationTitle(self.navigationTitle) 19 | .toolbar { self.dismissButton() } 20 | } 21 | .animation(.default, value: self.ⓒonvertedText == nil) 22 | .task { self.ⓒonvertedText = 📚TextConvert.encodeToTSV(self.model.notes) } 23 | .frame(width: 500, height: 440) 24 | } 25 | } 26 | 27 | private extension 📤NotesExportSheetView { 28 | private var navigationTitle: LocalizedStringKey { 29 | if self.model.notes.isEmpty { 30 | "Export notes as tsv text" 31 | } else if self.model.notes.count == 1 { 32 | "Export a note as tsv text" 33 | } else { 34 | "Export \(self.model.notes.count) notes as tsv text" 35 | } 36 | } 37 | private static func exampleView(_ ⓒonvertedText: String) -> some View { 38 | ScrollView { 39 | Text(ⓒonvertedText) 40 | .font(.subheadline.monospaced().italic()) 41 | .textSelection(.enabled) 42 | .padding() 43 | } 44 | } 45 | private func dismissButton() -> some ToolbarContent { 46 | ToolbarItem(placement: .automatic) { 47 | Button("Dismiss") { 48 | self.model.presentedSheetOnContentView = nil 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /iOS/📥NotesImport/📥NotesImportSheetView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📥NotesImportSheetView: View { 4 | @StateObject private var model: 📥NotesImportModel = .init() 5 | var body: some View { 6 | NavigationStack(path: self.$model.navigationPath) { 7 | List { 8 | self.inputModePicker() 9 | switch self.model.inputMode { 10 | case .file: 📥FileImportSection() 11 | case .text: 📥TextImportSection() 12 | } 13 | 📥InputExample() 14 | Self.notSupportMultiLineTextInNoteSection() 15 | } 16 | .environmentObject(self.model) 17 | .navigationDestination(for: String.self) { 18 | 📥ConvertedNotesMenu(importedText: $0) 19 | .environmentObject(self.model) 20 | } 21 | .navigationTitle("Import notes") 22 | .toolbar { 📰DismissButton() } 23 | } 24 | } 25 | } 26 | 27 | private extension 📥NotesImportSheetView { 28 | private func inputModePicker() -> some View { 29 | Section { 30 | Picker(selection: self.$model.inputMode) { 31 | Label("File", systemImage: "doc") 32 | .tag(📥InputMode.file) 33 | Label("Text", systemImage: "text.justify.left") 34 | .tag(📥InputMode.text) 35 | } label: { 36 | Label("Mode", systemImage: "tray.and.arrow.down") 37 | } 38 | .pickerStyle(.segmented) 39 | .listRowBackground(Color.clear) 40 | } 41 | } 42 | private static func notSupportMultiLineTextInNoteSection() -> some View { 43 | Section { 44 | Text("Not support multi line text in note.") 45 | .foregroundStyle(.secondary) 46 | } header: { 47 | Text("Directions") 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /MemorizeWidget.xcodeproj/xcuserdata/meisei.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MWShareExtension.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 2 11 | 12 | MWWidgetExtension.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | ShareExtension for iOS.xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 4 21 | 22 | Widget for iOS.xcscheme_^#shared#^_ 23 | 24 | orderHint 25 | 2 26 | 27 | Widget for watchOS.xcscheme_^#shared#^_ 28 | 29 | orderHint 30 | 3 31 | 32 | iOS.xcscheme_^#shared#^_ 33 | 34 | orderHint 35 | 0 36 | 37 | watchOS.xcscheme_^#shared#^_ 38 | 39 | orderHint 40 | 1 41 | 42 | 43 | SuppressBuildableAutocreation 44 | 45 | F568F18C29E3A5DA005A1D1A 46 | 47 | primary 48 | 49 | 50 | F568F1F329E3C565005A1D1A 51 | 52 | primary 53 | 54 | 55 | F5B5A45D28C6EDA1005B6E0F 56 | 57 | primary 58 | 59 | 60 | F5CEA5F02924AAAC00752277 61 | 62 | primary 63 | 64 | 65 | F5D30CC428C6F6C8001198AF 66 | 67 | primary 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /macOS/📥NotesImport/📥ConvertedNotesMenu.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📥ConvertedNotesMenu: View { 4 | @EnvironmentObject var model: 📥NotesImportModel 5 | var importedText: String 6 | var body: some View { 7 | Form { 8 | 📥SeparatorPicker() 9 | self.convertedNotesSection() 10 | } 11 | .formStyle(.grouped) 12 | .navigationTitle("Convert result") 13 | .toolbar { 14 | Self.SubmitButton(self.convertedNotes) 15 | } 16 | } 17 | } 18 | 19 | private extension 📥ConvertedNotesMenu { 20 | private var convertedNotes: 📚Notes { 21 | 📚TextConvert.decode(self.importedText, self.model.separator) 22 | } 23 | private func convertedNotesSection() -> some View { 24 | Section { 25 | ForEach(self.convertedNotes) { ⓝote in 26 | VStack(alignment: .leading) { 27 | Text(ⓝote.title) 28 | .font(.headline) 29 | Text(ⓝote.comment) 30 | .font(.footnote) 31 | } 32 | .foregroundStyle(.secondary) 33 | .padding(.vertical, 8) 34 | } 35 | } header: { 36 | Text("Notes count: \(self.convertedNotes.count)") 37 | } 38 | } 39 | private struct SubmitButton: ToolbarContent { 40 | @EnvironmentObject var model: 📱AppModel 41 | var convertedNotes: 📚Notes 42 | var body: some ToolbarContent { 43 | ToolbarItem(placement: .primaryAction) { 44 | Button { 45 | self.model.submitNotesImport(self.convertedNotes) 46 | } label: { 47 | Label("Submit", systemImage: "checkmark") 48 | } 49 | } 50 | } 51 | init(_ convertedNotes: 📚Notes) { 52 | self.convertedNotes = convertedNotes 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /iOS/📱AppModel(extension).swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension 📱AppModel { 4 | func apply(_ ⓘnputtedNote: 📗Note, target ⓣargetNote: 📗Note) { 5 | if let ⓘndex = self.notes.firstIndex(of: ⓣargetNote) { 6 | self.notes[ⓘndex].title = ⓘnputtedNote.title 7 | self.notes[ⓘndex].comment = ⓘnputtedNote.comment 8 | //Not copy UUID 9 | self.saveNotes() 10 | } 11 | } 12 | func addNewNoteBelow(_ ⓝote: 📗Note) { 13 | if let ⓘndex = self.notes.firstIndex(of: ⓝote) { 14 | self.addNewNote(index: ⓘndex + 1) 15 | } 16 | } 17 | var openedWidgetSingleNoteIndex: Int? { 18 | self.notes.index(self.openedWidgetNoteIDs.first) 19 | } 20 | func switchNotesListTab() { 21 | self.selectedTab = .notesList 22 | self.selectedSidebar = .notesList 23 | } 24 | func scrollTopByNewNoteShortcut(_ ⓤrl: URL, _ ⓢcrollViewProxy: ScrollViewProxy) { 25 | if case .newNoteShortcut = 🪧Tag.decode(ⓤrl) { 26 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { 27 | ⓢcrollViewProxy.scrollTo("NewNoteButton") 28 | } 29 | } 30 | } 31 | func addNewNoteByNewNoteShortcut() { 32 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) { 33 | self.addNewNoteOnTop() 34 | } 35 | } 36 | func handleToPresentADSheet() { 37 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) { 38 | if self.inAppPurchaseModel.checkToShowADSheet() { 39 | self.presentedSheetOnWidgetSheet = .ad 40 | } 41 | } 42 | } 43 | func dismissWidgetSheetOnBackground(_ ⓢcenePhase: ScenePhase) { 44 | if case .widget(_) = self.presentedSheetOnContentView, 45 | ⓢcenePhase == .background { 46 | self.presentedSheetOnWidgetSheet = nil 47 | self.presentedSheetOnContentView = nil 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /iOS/App Extensions/ShareExtension/Base.lproj/MainInterface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /macOS/📖WidgetSheet/📖SheetDebug.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📖SheetDebug: ViewModifier { 4 | @EnvironmentObject var model: 📱AppModel 5 | func body(content: Content) -> some View { 6 | content 7 | #if DEBUG 8 | .task { 9 | try? await Task.sleep(for: .seconds(1)) 10 | self.model.notes.insert(.init("Placeholder"), at: 0) 11 | self.model.notes.insert(.init("this is title", "This is comment. This is comment. This is comment. This is comment. This is comment."), at: 0) 12 | self.model.notes.insert(.init("this is title", "This is comment. This is comment. This is comment. This is comment. This is comment. This is comment. This is comment. This is comment. This is comment."), at: 0) 13 | self.model.notes.insert(.init("this is title", "This is comment. This is comment. This is comment. This is comment. This is comment.This is comment. This is comment. This is comment. This is comment. This is comment.This is comment. This is comment. This is comment. This is comment. This is comment.This is comment. This is comment. This is comment. This is comment. This is comment."), at: 0) 14 | self.model.notes.insert(.init("this is title", "This is comment. This is comment. This is comment. This is comment. This is comment.This is comment. This is comment. This is comment. This is comment. This is comment.This is comment. This is comment. This is comment. This is comment. This is comment.This is comment. This is comment. This is comment. This is comment. This is comment."), at: 0) 15 | self.model.saveNotes() 16 | self.model.presentedSheetOnContentView = 17 | .widget(.notes([ 18 | self.model.notes[0].id, 19 | self.model.notes[1].id, 20 | self.model.notes[2].id, 21 | self.model.notes[3].id, 22 | self.model.notes[4].id, 23 | ])) 24 | } 25 | #endif 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Shared/Supporting files/🌐Localization/🌐ADAppName.xcstrings: -------------------------------------------------------------------------------- 1 | { 2 | "sourceLanguage" : "en", 3 | "strings" : { 4 | "FadeInAlarm" : { 5 | "extractionState" : "manual", 6 | "localizations" : { 7 | "ja" : { 8 | "stringUnit" : { 9 | "state" : "translated", 10 | "value" : "" 11 | } 12 | } 13 | } 14 | }, 15 | "FlipByBlink" : { 16 | "extractionState" : "manual", 17 | "localizations" : { 18 | "ja" : { 19 | "stringUnit" : { 20 | "state" : "translated", 21 | "value" : "" 22 | } 23 | } 24 | } 25 | }, 26 | "LockInNote" : { 27 | "extractionState" : "manual", 28 | "localizations" : { 29 | "ja" : { 30 | "stringUnit" : { 31 | "state" : "translated", 32 | "value" : "ロックノート" 33 | } 34 | } 35 | } 36 | }, 37 | "MemorizeWidget" : { 38 | "extractionState" : "manual", 39 | "localizations" : { 40 | "ja" : { 41 | "stringUnit" : { 42 | "state" : "translated", 43 | "value" : "暗記ウィジェット" 44 | } 45 | } 46 | } 47 | }, 48 | "PlainShogiBoard" : { 49 | "extractionState" : "manual", 50 | "localizations" : { 51 | "ja" : { 52 | "stringUnit" : { 53 | "state" : "translated", 54 | "value" : "Plain将棋盤" 55 | } 56 | } 57 | } 58 | }, 59 | "TapTemperature" : { 60 | "extractionState" : "manual", 61 | "localizations" : { 62 | "ja" : { 63 | "stringUnit" : { 64 | "state" : "translated", 65 | "value" : "体温登録" 66 | } 67 | } 68 | } 69 | }, 70 | "TapWeight" : { 71 | "extractionState" : "manual", 72 | "localizations" : { 73 | "ja" : { 74 | "stringUnit" : { 75 | "state" : "translated", 76 | "value" : "体重登録" 77 | } 78 | } 79 | } 80 | } 81 | }, 82 | "version" : "1.0" 83 | } -------------------------------------------------------------------------------- /Shared/🔍Search/🔍SearchModel.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | class 🔍SearchModel: ObservableObject { 4 | @AppStorage(🎛️Key.Search.leadingText) 5 | var inputtedLeadingText: String = "" 6 | 7 | @AppStorage(🎛️Key.Search.trailingText) 8 | var trailingText: String = "" 9 | 10 | @AppStorage(🎛️Key.Search.openURLInOtherApp) 11 | var openURLInOtherApp: Bool = 🎛️Default.Search.openURLInOtherApp 12 | 13 | @Published var alertOpenURLFailure: Bool = false 14 | } 15 | 16 | extension 🔍SearchModel { 17 | func entireText(_ ⓠuery: String) -> String { 18 | "\(self.leadingText)\(ⓠuery)\(self.trailingText)" 19 | } 20 | func generateURL(_ ⓠuery: String) -> URL { 21 | guard let ⓔncodedText = Self.percentEncode(self.entireText(ⓠuery)), 22 | let ⓤrl = URL(string: ⓔncodedText) else { 23 | return Self.placeholderURL(ⓠuery) 24 | } 25 | 💥Feedback.light() 26 | return ⓤrl 27 | } 28 | var ableInAppSearch: Bool { 29 | if self.openURLInOtherApp { 30 | true 31 | } else { 32 | if self.inputtedLeadingText.hasPrefix("http://") 33 | || self.inputtedLeadingText.hasPrefix("https://") { 34 | true 35 | } else { 36 | if self.inputtedLeadingText.isEmpty, 37 | self.trailingText.isEmpty { 38 | true 39 | } else { 40 | false 41 | } 42 | } 43 | } 44 | } 45 | } 46 | 47 | private extension 🔍SearchModel { 48 | private var leadingText: String { 49 | if self.inputtedLeadingText.isEmpty { 50 | "https://duckduckgo.com/?q=" 51 | } else { 52 | self.inputtedLeadingText 53 | } 54 | } 55 | private static func percentEncode(_ ⓣext: String) -> String? { 56 | ⓣext.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) 57 | } 58 | private static func placeholderURL(_ ⓠuery: String) -> URL { 59 | .init(string: "https://duckduckgo.com/?q=\(ⓠuery)")! 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /iOS/📰Sheet/📰SheetHandlerOnContentView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📰SheetHandlerOnContentView: ViewModifier { 4 | @EnvironmentObject var model: 📱AppModel 5 | func body(content: Content) -> some View { 6 | content 7 | .sheet(item: self.$model.presentedSheetOnContentView) { 8 | switch $0 { 9 | case .widget: 📖WidgetSheetView() 10 | case .notesImport: 📥NotesImportSheetView() 11 | case .notesExport: 📤NotesExportSheetView() 12 | case .customizeFontSize: Self.fontCustomizeSheetView() 13 | case .customizeSearch: Self.customizeSearchSheetView() 14 | case .search(let ⓤrl): 🔍SearchSheetView(ⓤrl) 15 | case .dictionary(let ⓥiewController): 📘DictionarySheetView(ⓥiewController) 16 | case .aboutApp: Self.aboutAppSheetView() 17 | case .purchase: Self.purchaseSheetView() 18 | } 19 | } 20 | .modifier(📖DismissWidgetSheetOnBackground()) 21 | } 22 | } 23 | 24 | private extension 📰SheetHandlerOnContentView { 25 | private static func fontCustomizeSheetView() -> some View { 26 | NavigationStack { 27 | 🎛️FontSizeOptionMenu() 28 | .toolbar { 📰DismissButton() } 29 | } 30 | } 31 | private static func customizeSearchSheetView() -> some View { 32 | NavigationStack { 33 | 🔍CustomizeSearchMenu() 34 | .toolbar { 📰DismissButton() } 35 | } 36 | } 37 | private static func aboutAppSheetView() -> some View { 38 | NavigationStack { 39 | List { 40 | ℹ️AboutAppContent() 41 | } 42 | .navigationTitle(.init("About App", tableName: "🌐AboutApp")) 43 | .toolbar { 📰DismissButton() } 44 | } 45 | } 46 | private static func purchaseSheetView() -> some View { 47 | NavigationStack { 48 | 🛒InAppPurchaseMenu() 49 | .toolbar { 📰DismissButton() } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /iOS/📥NotesImport/📥TextImportSection.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct 📥TextImportSection: View { 4 | @EnvironmentObject var model: 📥NotesImportModel 5 | @FocusState private var textEditorFocus: Bool 6 | var body: some View { 7 | Section { 8 | 📥SeparatorPicker() 9 | TextEditor(text: self.$model.pastedText) 10 | .focused(self.$textEditorFocus) 11 | .font(.subheadline.monospaced()) 12 | .frame(height: 100) 13 | .padding(8) 14 | .overlay { 15 | if self.model.pastedText.isEmpty { 16 | Label("Paste the text here.", 17 | systemImage: "square.and.pencil") 18 | .font(.subheadline) 19 | .rotationEffect(.degrees(2)) 20 | .multilineTextAlignment(.center) 21 | .foregroundColor(.accentColor) 22 | .opacity(0.5) 23 | .allowsHitTesting(false) 24 | } 25 | } 26 | .toolbar { 27 | ToolbarItem(placement: .keyboard) { 28 | Button { 29 | self.textEditorFocus = false 30 | } label: { 31 | Label("Done", systemImage: "keyboard.chevron.compact.down") 32 | } 33 | } 34 | } 35 | Button { 36 | self.model.importPastedText() 37 | } label: { 38 | Label("Convert this text to notes", systemImage: "text.badge.plus") 39 | .padding(.vertical, 8) 40 | } 41 | .disabled(self.model.pastedText.isEmpty) 42 | } 43 | .animation(.default, value: self.model.pastedText.isEmpty) 44 | .alert("⚠️ Error", isPresented: self.$model.alertError) { 45 | Button("OK") { self.model.caughtError = nil } 46 | } message: { 47 | self.model.caughtError?.messageText() 48 | } 49 | } 50 | } 51 | --------------------------------------------------------------------------------