From 0573cd0ebea3b88fea06d047a0a83ac841a46b8a Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Sun, 8 Oct 2023 11:21:29 +0900 Subject: [PATCH 01/12] Fixed a State section --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 08d5bf4..3e3a601 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ However, this app is NOT a high performance note app so that you should use othe - Repository - https://github.com/3colorr/Mizuame-pages -# Current state -- main branch - - Releases +# Branch +- main + - Releases. - Others - Development. - It likely contain errors. From fcabd1970f2e3cd66fdf5cd9221ab76584fafc5a Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Sun, 8 Oct 2023 14:19:55 +0900 Subject: [PATCH 02/12] Added a description. --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 3e3a601..41b47e2 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,16 @@ The app Mizuame is a note on menu bar of Mac. However, this app is NOT a high performance note app so that you should use other better apps to save your important data. +What is a Good point about the Mizuame? +- It is simple with a few features. +- Quick access from the menu bar. +- Keep your desktop and dock clean. + +What is NOT SO GOOD point about the Mizuame? +- You cannot sync data with other devices. (e.g. iPad, Windows) +- This app cannot backup your data, so that your data may be lost unintentionally due to device failure. +- You cannot paste images. + # Website - Website - https://3colorr.github.io/Mizuame-pages/ From 8b2fbfc48017507a565a38e8c7f9c2c59f145039 Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Sun, 15 Oct 2023 15:00:21 +0900 Subject: [PATCH 03/12] Added a RedoUndo class for texteditor. --- Mizuame/DataModel/CalculateModel.swift | 8 ++++++ Mizuame/RedoUndo.swift | 36 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 Mizuame/DataModel/CalculateModel.swift create mode 100644 Mizuame/RedoUndo.swift diff --git a/Mizuame/DataModel/CalculateModel.swift b/Mizuame/DataModel/CalculateModel.swift new file mode 100644 index 0000000..90b082a --- /dev/null +++ b/Mizuame/DataModel/CalculateModel.swift @@ -0,0 +1,8 @@ +// +// CalculateModel.swift +// Mizuame +// +// Created by becomefoolish on 2023/10/14. +// + +import Foundation diff --git a/Mizuame/RedoUndo.swift b/Mizuame/RedoUndo.swift new file mode 100644 index 0000000..df0a223 --- /dev/null +++ b/Mizuame/RedoUndo.swift @@ -0,0 +1,36 @@ +// +// RedoUndo.swift +// Mizuame +// +// Created by Nakamura Akira(3colorr) on 2023/10/15. +// + +import Foundation + +class RedoUndo { + private let MAX_HISTORIES: Int = 30 + + private var currentIndex: Int = 0 + private var noteHistories: [String] = [] + + init(initialNote: String) { + noteHistories.append(initialNote) + } + + // Store snapshot of notes. + public func snapshot(of note: String) -> Bool { + return false + } + + // Return a next generation note. + // If there is no next generation, return the current generation. + public func redo() -> String { + return "" + } + + // Return a previous generation note. + // If there is no previous generation, return the current generation. + public func undo() -> String { + return "" + } +} From 6f9bf9ca2c4130cded650e4aef8fddabffde8870 Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Mon, 16 Oct 2023 23:01:30 +0900 Subject: [PATCH 04/12] Implemented a redo/undo --- Mizuame/ContentView.swift | 23 ++++++++++++++++++++ Mizuame/RedoUndo.swift | 45 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/Mizuame/ContentView.swift b/Mizuame/ContentView.swift index ada9aa7..6c86cef 100644 --- a/Mizuame/ContentView.swift +++ b/Mizuame/ContentView.swift @@ -43,6 +43,8 @@ struct ContentView: View { private let io: DataIO private var data: StickyNote + private let redoUndoManager: RedoUndo + init(delegate: AppDelegate) { self.delegate = delegate self.io = DataIO() @@ -54,6 +56,8 @@ struct ContentView: View { } _stickyText = State(initialValue: self.data.contents[0].body) + + redoUndoManager = RedoUndo(initialNote: self.data.contents[0].body) } var body: some View { @@ -90,6 +94,22 @@ struct ContentView: View { Spacer() .layoutPriority(1) + Button(action: { + stickyText = redoUndoManager.undo() + }, label: { + Image(systemName: "return.left") + }) + .hidden() + .keyboardShortcut("z", modifiers: [.command]) + + Button(action: { + stickyText = redoUndoManager.redo() + }, label: { + Image(systemName: "return.right") + }) + .hidden() + .keyboardShortcut("y", modifiers: [.command]) + if isPinNote { Image(systemName: "pin") .foregroundColor(Color.red) @@ -169,6 +189,9 @@ struct ContentView: View { .scrollContentBackground(.hidden) .background(Color(bodyBackgroundTheme)) .onChange(of: stickyText) { val in + + _ = redoUndoManager.snapshot(of: val) + if isExecutableSave { Task { do { diff --git a/Mizuame/RedoUndo.swift b/Mizuame/RedoUndo.swift index df0a223..ee4686a 100644 --- a/Mizuame/RedoUndo.swift +++ b/Mizuame/RedoUndo.swift @@ -13,24 +13,65 @@ class RedoUndo { private var currentIndex: Int = 0 private var noteHistories: [String] = [] + private var isSkipSnapshot: Bool = false + init(initialNote: String) { noteHistories.append(initialNote) } // Store snapshot of notes. + // If user was executing redo or undo, this function is not store snapshot of note. public func snapshot(of note: String) -> Bool { + + if isSkipSnapshot { + isSkipSnapshot = false return false + } + + if noteHistories.count == MAX_HISTORIES { + noteHistories.removeFirst() + noteHistories.append(note) + currentIndex = noteHistories.count - 1 + + return true + } + + if currentIndex < noteHistories.count - 1 { + noteHistories.removeSubrange((currentIndex + 1).. String { - return "" + if currentIndex + 1 < MAX_HISTORIES { + currentIndex += 1 + } + + isSkipSnapshot = true + + return noteHistories[currentIndex] } // Return a previous generation note. // If there is no previous generation, return the current generation. public func undo() -> String { - return "" + if currentIndex > 0 { + currentIndex -= 1 + } + + isSkipSnapshot = true + + return noteHistories[currentIndex] } } From 32ae75133c4d4119df25f501e4d44c592ac5ca1a Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Mon, 16 Oct 2023 23:02:16 +0900 Subject: [PATCH 05/12] Implemented a test for RedoUndo class. --- MizuameTests/MizuameTests.swift | 70 +++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/MizuameTests/MizuameTests.swift b/MizuameTests/MizuameTests.swift index c794896..457c3a7 100644 --- a/MizuameTests/MizuameTests.swift +++ b/MizuameTests/MizuameTests.swift @@ -64,4 +64,74 @@ final class MizuameTests: XCTestCase { XCTAssertEqual(data?.contents[1].markercolor, "000000") XCTAssertEqual(data?.contents[1].body, "test2") } + + // Test RedoUndo class. + // + // String data for testing + // testText = "abc" + // Prepare + // RedoUndo instance is initialized with testText. + // + // test 1: Store testText. + // expected 1: snapshot(of note: String) returns true. + // + // test 2: Add "efg" to testText then store testText. + // expected 2: snapshot(of note: String) returns true. + // + // test 3: Run "Undo". + // expected 3: undo() returns "abc". + // + // test 4: Run "Redo". + // expected 4: redo() returns "abcefg". + // + // test 5: Run "Undo" then store testText. + // expected 5-1: undo() returns "abc". + // expected 5-2: snapshot(of note: String) returns false. + // + // test 6: Run "Undo" again.(A lower limit of redo/undo history test) + // expected 7: undo() returns "abc". + // + // test 7: Store testText while add "x(=1...30)" to one then Run "Undo" 30 times. + // (A upper limit of redo/undo history test) + // expected 8: 30th undo() returns "abc1". + // + func testRedoUndo() throws { + var testText = "abc" + let manager = RedoUndo(initialNote: testText) + + // test 1 + XCTAssertTrue(manager.snapshot(of: testText)) + + // test 2 + testText += "efg" + XCTAssertTrue(manager.snapshot(of: testText)) + + // test 3 + XCTAssertEqual(manager.undo(), "abc") + + // test 4 + XCTAssertEqual(manager.redo(), "abcefg") + + // test 5 + testText = manager.undo() + XCTAssertEqual(testText, "abc") + XCTAssertFalse(manager.snapshot(of: testText)) + + // test 6 + testText = manager.undo() + XCTAssertEqual(testText, "abc") + + // test 7 + XCTAssertFalse(manager.snapshot(of: testText)) + for x in 1...30 { + testText += String(x) + _ = manager.snapshot(of: testText) + } + + for _ in 1...30 { + _ = manager.undo() + } + + XCTAssertEqual(manager.undo(), "abc1") + } } From b429ba7dd4f2777ededf068f404eb7caec550610 Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Tue, 17 Oct 2023 22:22:53 +0900 Subject: [PATCH 06/12] bugfix --- Mizuame/RedoUndo.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mizuame/RedoUndo.swift b/Mizuame/RedoUndo.swift index ee4686a..e6b070d 100644 --- a/Mizuame/RedoUndo.swift +++ b/Mizuame/RedoUndo.swift @@ -54,12 +54,10 @@ class RedoUndo { // Return a next generation note. // If there is no next generation, return the current generation. public func redo() -> String { - if currentIndex + 1 < MAX_HISTORIES { + if currentIndex + 1 < noteHistories.count { currentIndex += 1 } - isSkipSnapshot = true - return noteHistories[currentIndex] } From 2c964370cb768bb7620752ceb2e169f9fd936c86 Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Tue, 17 Oct 2023 22:24:05 +0900 Subject: [PATCH 07/12] Refactoring --- Mizuame/RedoUndo.swift | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Mizuame/RedoUndo.swift b/Mizuame/RedoUndo.swift index e6b070d..83299bb 100644 --- a/Mizuame/RedoUndo.swift +++ b/Mizuame/RedoUndo.swift @@ -13,8 +13,6 @@ class RedoUndo { private var currentIndex: Int = 0 private var noteHistories: [String] = [] - private var isSkipSnapshot: Bool = false - init(initialNote: String) { noteHistories.append(initialNote) } @@ -23,8 +21,7 @@ class RedoUndo { // If user was executing redo or undo, this function is not store snapshot of note. public func snapshot(of note: String) -> Bool { - if isSkipSnapshot { - isSkipSnapshot = false + if note == noteHistories[currentIndex] { return false } @@ -68,8 +65,6 @@ class RedoUndo { currentIndex -= 1 } - isSkipSnapshot = true - return noteHistories[currentIndex] } } From 61277f38e2443b30e3374194141e6dc1cf144200 Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Tue, 17 Oct 2023 22:24:28 +0900 Subject: [PATCH 08/12] Fixed a Redo/Undo test --- MizuameTests/MizuameTests.swift | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/MizuameTests/MizuameTests.swift b/MizuameTests/MizuameTests.swift index 457c3a7..1d89054 100644 --- a/MizuameTests/MizuameTests.swift +++ b/MizuameTests/MizuameTests.swift @@ -72,57 +72,57 @@ final class MizuameTests: XCTestCase { // Prepare // RedoUndo instance is initialized with testText. // - // test 1: Store testText. + // test 1: Add "efg" to testText then store testText. // expected 1: snapshot(of note: String) returns true. // - // test 2: Add "efg" to testText then store testText. - // expected 2: snapshot(of note: String) returns true. + // test 2: Run "Undo". + // expected 2: undo() returns "abc". // - // test 3: Run "Undo". - // expected 3: undo() returns "abc". + // test 3: Run "Redo". + // expected 3: redo() returns "abcefg". // - // test 4: Run "Redo". + // test 4: Run "Redo" again.(A upper limit of redo history test) // expected 4: redo() returns "abcefg". // // test 5: Run "Undo" then store testText. // expected 5-1: undo() returns "abc". // expected 5-2: snapshot(of note: String) returns false. + // Because can not store same strings. // - // test 6: Run "Undo" again.(A lower limit of redo/undo history test) - // expected 7: undo() returns "abc". + // test 6: Run "Undo" again.(A lower limit of undo history test) + // expected 6: undo() returns "abc". // // test 7: Store testText while add "x(=1...30)" to one then Run "Undo" 30 times. - // (A upper limit of redo/undo history test) - // expected 8: 30th undo() returns "abc1". + // (A upper limit of history test) + // expected 7: 30th undo() returns "abc1". // func testRedoUndo() throws { var testText = "abc" let manager = RedoUndo(initialNote: testText) // test 1 - XCTAssertTrue(manager.snapshot(of: testText)) - - // test 2 testText += "efg" XCTAssertTrue(manager.snapshot(of: testText)) - // test 3 + // test 2 XCTAssertEqual(manager.undo(), "abc") + // test 3 + XCTAssertEqual(manager.redo(), "abcefg") + // test 4 XCTAssertEqual(manager.redo(), "abcefg") - + // test 5 testText = manager.undo() - XCTAssertEqual(testText, "abc") - XCTAssertFalse(manager.snapshot(of: testText)) + XCTAssertEqual(testText, "abc") //5-1 + XCTAssertFalse(manager.snapshot(of: testText)) //5-2 // test 6 testText = manager.undo() XCTAssertEqual(testText, "abc") - + // test 7 - XCTAssertFalse(manager.snapshot(of: testText)) for x in 1...30 { testText += String(x) _ = manager.snapshot(of: testText) From 0293375522bdba3063301766525f42ded3197f39 Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Wed, 18 Oct 2023 22:24:46 +0900 Subject: [PATCH 09/12] Added keyboard shortcut of settings. --- Mizuame/ContentView.swift | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Mizuame/ContentView.swift b/Mizuame/ContentView.swift index 6c86cef..bfd6176 100644 --- a/Mizuame/ContentView.swift +++ b/Mizuame/ContentView.swift @@ -153,6 +153,7 @@ struct ContentView: View { .foregroundColor(Color(bodyForegroundTheme)) } .buttonStyle(SettingsLinkStyle()) + .keyboardShortcut(",", modifiers: [.command]) .onHover { _ in isShowMessagebar = false userAction = .NONE @@ -161,14 +162,16 @@ struct ContentView: View { // .onTapGesture {} } else { - Image(systemName: "gearshape.fill") - .foregroundColor(Color(bodyForegroundTheme)) - .onTapGesture { - isShowMessagebar = false - userAction = .NONE - - delegate.showSettings() - } + Button(action: { + isShowMessagebar = false + userAction = .NONE + delegate.showSettings() + }, label: { + Image(systemName: "gearshape.fill") + .foregroundColor(Color(bodyForegroundTheme)) + }) + .buttonStyle(SettingsLinkStyle()) + .keyboardShortcut(",", modifiers: [.command]) } } .padding(EdgeInsets(top: 5, leading: 10, bottom: 5, trailing: 10)) From 6a40fe0e846d387815f6ac405c18cd1e33069f68 Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Wed, 18 Oct 2023 22:29:33 +0900 Subject: [PATCH 10/12] Fixed a formatter for note size text field. --- Mizuame/Settings/SettingKeys.swift | 8 +++---- Mizuame/Settings/TabStickyNote.swift | 34 +++++++++++----------------- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/Mizuame/Settings/SettingKeys.swift b/Mizuame/Settings/SettingKeys.swift index a34039f..004cba1 100644 --- a/Mizuame/Settings/SettingKeys.swift +++ b/Mizuame/Settings/SettingKeys.swift @@ -73,10 +73,10 @@ struct SettingKeys { let keyHeight: String = "stickyNoteHeight" let initialWidth: Int = 300 let initialHeight: Int = 150 - let minWidth: Int = 150 - let maxWidth: Int = 1000 - let minHeight: Int = 80 - let maxHeight: Int = 1000 + let minWidth: NSNumber = 200 + let maxWidth: NSNumber = 1000 + let minHeight: NSNumber = 100 + let maxHeight: NSNumber = 1000 let keyPinNote: String = "stickyNotePin" let initialPinNote: Bool = false diff --git a/Mizuame/Settings/TabStickyNote.swift b/Mizuame/Settings/TabStickyNote.swift index 157c743..d810051 100644 --- a/Mizuame/Settings/TabStickyNote.swift +++ b/Mizuame/Settings/TabStickyNote.swift @@ -33,11 +33,19 @@ struct TabStickyNote: View { private let INIT_BODY_BACKGROUND_THEME: String = SettingKeys.StickyNoteColor().initialBackgroundTheme private let INIT_FRAME_THEME: String = SettingKeys.FrameColor().initialTheme - private var numberFormatter = NumberFormatter() + private var noteWidthFormatter = NumberFormatter() + private var noteHeightFormatter = NumberFormatter() init() { - numberFormatter.minimumIntegerDigits = 1 - numberFormatter.maximumIntegerDigits = 4 + noteWidthFormatter.minimumIntegerDigits = 1 + noteWidthFormatter.maximumIntegerDigits = 4 + noteWidthFormatter.minimum = SettingKeys.StickyNote().minWidth + noteWidthFormatter.maximum = SettingKeys.StickyNote().maxWidth + + noteHeightFormatter.minimumIntegerDigits = 1 + noteHeightFormatter.maximumIntegerDigits = 4 + noteHeightFormatter.minimum = SettingKeys.StickyNote().minHeight + noteHeightFormatter.maximum = SettingKeys.StickyNote().maxHeight } var body: some View { @@ -70,30 +78,14 @@ struct TabStickyNote: View { HStack { Text("settings.tab.stickynote.window.size.width") - TextField("\(INIT_WIDTH)", value: $width, formatter: NumberFormatter()) + TextField("\(INIT_WIDTH)", value: $width, formatter: noteWidthFormatter) .frame(width: 80) .padding(EdgeInsets(top: 2, leading: 0, bottom: 2, trailing: 10)) - .onChange(of: width) { val in - if val < SettingKeys.StickyNote().minWidth { - width = SettingKeys.StickyNote().minWidth - } - if val > SettingKeys.StickyNote().maxWidth { - width = SettingKeys.StickyNote().maxWidth - } - } Text("settings.tab.stickynote.window.size.height") - TextField("\(INIT_HEIGHT)", value: $height, formatter: NumberFormatter()) + TextField("\(INIT_HEIGHT)", value: $height, formatter: noteHeightFormatter) .frame(width: 80) .padding(EdgeInsets(top: 2, leading: 10, bottom: 2, trailing: 0)) - .onChange(of: height) { val in - if val < SettingKeys.StickyNote().minHeight { - height = SettingKeys.StickyNote().minHeight - } - if val > SettingKeys.StickyNote().maxHeight { - height = SettingKeys.StickyNote().maxHeight - } - } } Text("settings.tab.stickynote.theme") From 22b7b7dc3843ad6bb0779b5b70f0e42f7be63c3a Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Wed, 18 Oct 2023 22:50:40 +0900 Subject: [PATCH 11/12] Changed layout priority. --- Mizuame/ContentView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mizuame/ContentView.swift b/Mizuame/ContentView.swift index bfd6176..851a21f 100644 --- a/Mizuame/ContentView.swift +++ b/Mizuame/ContentView.swift @@ -88,7 +88,7 @@ struct ContentView: View { if isShowSavingMessage && !isExecutableSave { Text("sitickynote.menu.message.saving") .padding(.horizontal, 5) - .layoutPriority(1) + .layoutPriority(2) } Spacer() From 0641c0b90f27633437df1d201137e7cfb022e496 Mon Sep 17 00:00:00 2001 From: 3colorr <3colorr@gmail.com> Date: Thu, 19 Oct 2023 08:07:49 +0900 Subject: [PATCH 12/12] Changed version --- Mizuame/Settings/TabInfo.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mizuame/Settings/TabInfo.swift b/Mizuame/Settings/TabInfo.swift index aa9b37e..47633ba 100644 --- a/Mizuame/Settings/TabInfo.swift +++ b/Mizuame/Settings/TabInfo.swift @@ -30,7 +30,7 @@ struct TabInfo: View { } VStack(alignment: .leading, spacing: 5) { - Text("Version: 1.1.2").font(.body) + Text("Version: 1.1.3").font(.body) Text("License: MIT license").font(.body) HStack { Text("settings.tab.info.src").font(.body)