diff --git a/Calendr.xcodeproj/project.pbxproj b/Calendr.xcodeproj/project.pbxproj index fa47987..6ff6867 100644 --- a/Calendr.xcodeproj/project.pbxproj +++ b/Calendr.xcodeproj/project.pbxproj @@ -1491,7 +1491,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.14.6; + MARKETING_VERSION = 1.14.7; PRODUCT_BUNDLE_IDENTIFIER = br.paker.Calendr; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Calendr/Config/Calendr-Bridging-Header.h"; @@ -1519,7 +1519,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.14.6; + MARKETING_VERSION = 1.14.7; PRODUCT_BUNDLE_IDENTIFIER = br.paker.Calendr; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Calendr/Config/Calendr-Bridging-Header.h"; diff --git a/Calendr.xcodeproj/xcshareddata/xcschemes/Calendr.xcscheme b/Calendr.xcodeproj/xcshareddata/xcschemes/Calendr.xcscheme index 30d8572..755360f 100644 --- a/Calendr.xcodeproj/xcshareddata/xcschemes/Calendr.xcscheme +++ b/Calendr.xcodeproj/xcshareddata/xcschemes/Calendr.xcscheme @@ -130,6 +130,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "pt" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Calendr/Assets/Strings.generated.swift b/Calendr/Assets/Strings.generated.swift index 61c10c5..23ab38c 100644 --- a/Calendr/Assets/Strings.generated.swift +++ b/Calendr/Assets/Strings.generated.swift @@ -221,10 +221,16 @@ internal enum Strings { internal enum NextEvent { /// Shorten if 'notch' is present internal static let detectNotch = Strings.tr("Localizable", "settings.next_event.detect_notch", fallback: "Shorten if 'notch' is present") - /// Font size - internal static let fontSize = Strings.tr("Localizable", "settings.next_event.font_size", fallback: "Font size") + /// Grab attention when event is close + internal static let grabAttention = Strings.tr("Localizable", "settings.next_event.grab_attention", fallback: "Grab attention when event is close") /// Show next event internal static let showNextEvent = Strings.tr("Localizable", "settings.next_event.show_next_event", fallback: "Show next event") + internal enum GrabAttention { + /// Flashing + internal static let flashing = Strings.tr("Localizable", "settings.next_event.grab_attention.flashing", fallback: "Flashing") + /// Play sound + internal static let sound = Strings.tr("Localizable", "settings.next_event.grab_attention.sound", fallback: "Play sound") + } } internal enum Tab { /// About diff --git a/Calendr/Assets/cs.lproj/Localizable.strings b/Calendr/Assets/cs.lproj/Localizable.strings index db874b7..511b03f 100644 --- a/Calendr/Assets/cs.lproj/Localizable.strings +++ b/Calendr/Assets/cs.lproj/Localizable.strings @@ -38,7 +38,9 @@ "settings.next_event" = "Další událost"; "settings.next_event.show_next_event" = "Zobrazit další událost"; -"settings.next_event.font_size" = "Velikost písma"; +//"settings.next_event.grab_attention" = "Grab attention when event is close"; +//"settings.next_event.grab_attention.flashing" = "Flashing"; +//"settings.next_event.grab_attention.sound" = "Play sound"; "settings.next_event.detect_notch" = "Zkrátit, pokud je 'výřez' přítomen"; "settings.calendar" = "Kalendář"; diff --git a/Calendr/Assets/de.lproj/Localizable.strings b/Calendr/Assets/de.lproj/Localizable.strings index 72ed271..3d3d5bd 100644 --- a/Calendr/Assets/de.lproj/Localizable.strings +++ b/Calendr/Assets/de.lproj/Localizable.strings @@ -38,7 +38,9 @@ "settings.next_event" = "Nächster Termin"; "settings.next_event.show_next_event" = "Zeige nächsten Termin"; -"settings.next_event.font_size" = "Schriftgröße"; +//"settings.next_event.grab_attention" = "Grab attention when event is close"; +//"settings.next_event.grab_attention.flashing" = "Flashing"; +//"settings.next_event.grab_attention.sound" = "Play sound"; "settings.next_event.detect_notch" = "Kürzen, wenn 'notch' vorhanden ist"; "settings.calendar" = "Kalender"; diff --git a/Calendr/Assets/en.lproj/Localizable.strings b/Calendr/Assets/en.lproj/Localizable.strings index 2b457c2..40e75cd 100644 --- a/Calendr/Assets/en.lproj/Localizable.strings +++ b/Calendr/Assets/en.lproj/Localizable.strings @@ -38,7 +38,9 @@ "settings.next_event" = "Next Event"; "settings.next_event.show_next_event" = "Show next event"; -"settings.next_event.font_size" = "Font size"; +"settings.next_event.grab_attention" = "Grab attention when event is close"; +"settings.next_event.grab_attention.flashing" = "Flashing"; +"settings.next_event.grab_attention.sound" = "Play sound"; "settings.next_event.detect_notch" = "Shorten if 'notch' is present"; "settings.calendar" = "Calendar"; diff --git a/Calendr/Assets/es.lproj/Localizable.strings b/Calendr/Assets/es.lproj/Localizable.strings index 5ff633f..27d5f45 100644 --- a/Calendr/Assets/es.lproj/Localizable.strings +++ b/Calendr/Assets/es.lproj/Localizable.strings @@ -38,7 +38,9 @@ "settings.next_event" = "Próximo evento"; "settings.next_event.show_next_event" = "Mostrar próximo evento"; -"settings.next_event.font_size" = "Tamaño de fuente"; +//"settings.next_event.grab_attention" = "Grab attention when event is close"; +//"settings.next_event.grab_attention.flashing" = "Flashing"; +//"settings.next_event.grab_attention.sound" = "Play sound"; "settings.next_event.detect_notch" = "Acortar si 'notch' está presente"; "settings.calendar" = "Calendario"; diff --git a/Calendr/Assets/fr.lproj/Localizable.strings b/Calendr/Assets/fr.lproj/Localizable.strings index 6b9d682..0f72f4b 100644 --- a/Calendr/Assets/fr.lproj/Localizable.strings +++ b/Calendr/Assets/fr.lproj/Localizable.strings @@ -38,7 +38,9 @@ "settings.next_event" = "Prochain événement"; "settings.next_event.show_next_event" = "Afficher prochain événement"; -"settings.next_event.font_size" = "Taille de police"; +//"settings.next_event.grab_attention" = "Grab attention when event is close"; +//"settings.next_event.grab_attention.flashing" = "Flashing"; +//"settings.next_event.grab_attention.sound" = "Play sound"; "settings.next_event.detect_notch" = "Raccourcir si 'notch' est présent"; "settings.calendar" = "Calendrier"; diff --git a/Calendr/Assets/it.lproj/Localizable.strings b/Calendr/Assets/it.lproj/Localizable.strings index 4075d7a..f0f5f97 100644 --- a/Calendr/Assets/it.lproj/Localizable.strings +++ b/Calendr/Assets/it.lproj/Localizable.strings @@ -39,7 +39,9 @@ "settings.next_event" = "Prossimo evento"; "settings.next_event.show_next_event" = "Mostra il prossimo evento"; -"settings.next_event.font_size" = "Dimensione del font"; +//"settings.next_event.grab_attention" = "Grab attention when event is close"; +//"settings.next_event.grab_attention.flashing" = "Flashing"; +//"settings.next_event.grab_attention.sound" = "Play sound"; "settings.next_event.detect_notch" = "Più corto se c'è il 'notch'"; "settings.calendar" = "Calendario"; diff --git a/Calendr/Assets/pt.lproj/Localizable.strings b/Calendr/Assets/pt.lproj/Localizable.strings index c186634..536bba3 100644 --- a/Calendr/Assets/pt.lproj/Localizable.strings +++ b/Calendr/Assets/pt.lproj/Localizable.strings @@ -38,7 +38,9 @@ "settings.next_event" = "Próximo Evento"; "settings.next_event.show_next_event" = "Mostrar próximo evento"; -"settings.next_event.font_size" = "Tamanho da fonte"; +"settings.next_event.grab_attention" = "Chamar atenção quando o evento estiver próximo"; +"settings.next_event.grab_attention.flashing" = "Piscando"; +"settings.next_event.grab_attention.sound" = "Tocar som"; "settings.next_event.detect_notch" = "Encurtar se 'notch' estiver presente"; "settings.calendar" = "Calendário"; diff --git a/Calendr/Assets/sk.lproj/Localizable.strings b/Calendr/Assets/sk.lproj/Localizable.strings index 5902237..b318a50 100644 --- a/Calendr/Assets/sk.lproj/Localizable.strings +++ b/Calendr/Assets/sk.lproj/Localizable.strings @@ -38,7 +38,9 @@ "settings.next_event" = "Ďalšia udalosť"; "settings.next_event.show_next_event" = "Zobraziť ďalšiu udalosť"; -"settings.next_event.font_size" = "Veľkosť písma"; +//"settings.next_event.grab_attention" = "Grab attention when event is close"; +//"settings.next_event.grab_attention.flashing" = "Flashing"; +//"settings.next_event.grab_attention.sound" = "Play sound"; "settings.next_event.detect_notch" = "Skrátiť, ak je prítomný 'výrez'"; "settings.calendar" = "Kalendár"; diff --git a/Calendr/Assets/sv.lproj/Localizable.strings b/Calendr/Assets/sv.lproj/Localizable.strings index 5fa1db9..d2674f8 100644 --- a/Calendr/Assets/sv.lproj/Localizable.strings +++ b/Calendr/Assets/sv.lproj/Localizable.strings @@ -38,7 +38,9 @@ "settings.next_event" = "Nästa händelse"; "settings.next_event.show_next_event" = "Visa nästa händelse"; -"settings.next_event.font_size" = "Teckenstorlek"; +//"settings.next_event.grab_attention" = "Grab attention when event is close"; +//"settings.next_event.grab_attention.flashing" = "Flashing"; +//"settings.next_event.grab_attention.sound" = "Play sound"; "settings.next_event.detect_notch" = "Korta om 'notch' finns"; "settings.calendar" = "Kalender"; diff --git a/Calendr/Assets/zh-Hans.lproj/Localizable.strings b/Calendr/Assets/zh-Hans.lproj/Localizable.strings index 294557b..d5aff51 100644 --- a/Calendr/Assets/zh-Hans.lproj/Localizable.strings +++ b/Calendr/Assets/zh-Hans.lproj/Localizable.strings @@ -38,7 +38,9 @@ "settings.next_event" = "下一个日程"; "settings.next_event.show_next_event" = "显示下一个日程"; -"settings.next_event.font_size" = "字体大小"; +//"settings.next_event.grab_attention" = "Grab attention when event is close"; +//"settings.next_event.grab_attention.flashing" = "Flashing"; +//"settings.next_event.grab_attention.sound" = "Play sound"; "settings.next_event.detect_notch" = "为屏幕“刘海”缩短长度"; "settings.calendar" = "日历"; diff --git a/Calendr/Assets/zh-Hant-TW.lproj/Localizable.strings b/Calendr/Assets/zh-Hant-TW.lproj/Localizable.strings index 3c8c76a..df6f2a2 100644 --- a/Calendr/Assets/zh-Hant-TW.lproj/Localizable.strings +++ b/Calendr/Assets/zh-Hant-TW.lproj/Localizable.strings @@ -38,7 +38,9 @@ "settings.next_event" = "下一個事件"; "settings.next_event.show_next_event" = "顯示下一個事件"; -"settings.next_event.font_size" = "字型大小"; +//"settings.next_event.grab_attention" = "Grab attention when event is close"; +//"settings.next_event.grab_attention.flashing" = "Flashing"; +//"settings.next_event.grab_attention.sound" = "Play sound"; "settings.next_event.detect_notch" = "若有 '瀏海' 則縮短"; "settings.calendar" = "行事曆"; diff --git a/Calendr/MenuBar/NextEventViewModel.swift b/Calendr/MenuBar/NextEventViewModel.swift index 6256c70..93d8f60 100644 --- a/Calendr/MenuBar/NextEventViewModel.swift +++ b/Calendr/MenuBar/NextEventViewModel.swift @@ -169,7 +169,10 @@ class NextEventViewModel { backgroundColor = nextEventObservable .skipNil() - .map { [dateProvider] nextEvent in + .withLatestFrom( + Observable.combineLatest(settings.eventStatusItemFlashing, settings.eventStatusItemSound) + ) { ($0, $1.0, $1.1) } + .map { [dateProvider] nextEvent, flashing, sound in guard !nextEvent.isInProgress else { return nextEvent.event.calendar.color.withAlphaComponent(0.2) @@ -179,26 +182,28 @@ class NextEventViewModel { guard let minutes = diff.minute, let seconds = diff.second else { return .clear } - // play when event starts - if minutes == 0 && seconds == 0 { - DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) { - soundPlayer.play(.glass) + if sound { + // play at 5 minutes + if minutes == 5 && seconds == 0 { + soundPlayer.play(.ping) } - } - // play at 5 minutes + 1 minute to start - if [1, 5].contains(minutes) && seconds == 0 { - soundPlayer.play(.ping) + // play at 30 seconds to start + if minutes == 0 && seconds == 30 { + soundPlayer.play(.ping) + } } - // flash continuously under 30 seconds to start - if minutes == 0 && seconds <= 30 { - return seconds % 2 == 0 ? .systemRed : .clear - } + if flashing { + // flash continuously under 30 seconds to start + if minutes == 0 && seconds <= 30 { + return seconds % 2 == 0 ? .systemRed : .clear + } - // flash 5x every minute - if minutes <= 5 { - return seconds > 50 && seconds % 2 == 1 ? .systemRed : .clear + // flash 5x every minute + if minutes <= 5 { + return seconds > 50 && seconds % 2 == 1 ? .systemRed : .clear + } } return .clear diff --git a/Calendr/Mocks/MockNextEventSettings.swift b/Calendr/Mocks/MockNextEventSettings.swift index 034c3c5..d00ab1f 100644 --- a/Calendr/Mocks/MockNextEventSettings.swift +++ b/Calendr/Mocks/MockNextEventSettings.swift @@ -14,19 +14,25 @@ class MockNextEventSettings: MockEventDetailsSettings, NextEventSettings { let showEventStatusItem: Observable let eventStatusItemTextScaling: Observable let eventStatusItemCheckRange: Observable + let eventStatusItemFlashing: Observable + let eventStatusItemSound: Observable let eventStatusItemLength: Observable let eventStatusItemDetectNotch: Observable init( showItem: Bool = true, - textScaling: Double = 1, checkRange: Int = 10, + flashing: Bool = true, + sound: Bool = true, + textScaling: Double = 1, length: Int = 20, detectNotch: Bool = false ) { showEventStatusItem = .just(showItem) - eventStatusItemTextScaling = .just(textScaling) eventStatusItemCheckRange = .just(checkRange) + eventStatusItemFlashing = .just(flashing) + eventStatusItemSound = .just(sound) + eventStatusItemTextScaling = .just(textScaling) eventStatusItemLength = .just(length) eventStatusItemDetectNotch = .just(detectNotch) } diff --git a/Calendr/Previews/NextEventPreview.swift b/Calendr/Previews/NextEventPreview.swift index 3d33a22..e194568 100644 --- a/Calendr/Previews/NextEventPreview.swift +++ b/Calendr/Previews/NextEventPreview.swift @@ -24,7 +24,7 @@ struct NextEventPreview: PreviewProvider { static let events: [EventModel] = [ .make( - start: dateProvider.now + 5, + start: dateProvider.now + 70, end: dateProvider.now + 999, title: "Test with a very long event name and some more extra text", type: .event(.accepted), diff --git a/Calendr/Settings/GeneralSettingsViewController.swift b/Calendr/Settings/GeneralSettingsViewController.swift index 9793f88..4cb3853 100644 --- a/Calendr/Settings/GeneralSettingsViewController.swift +++ b/Calendr/Settings/GeneralSettingsViewController.swift @@ -22,8 +22,14 @@ class GeneralSettingsViewController: NSViewController, SettingsUI { private let iconStyleDropdown = Dropdown() private let dateFormatDropdown = Dropdown() private let dateFormatTextField = NSTextField() + + // Next Event private let showNextEventCheckbox = Checkbox(title: Strings.Settings.NextEvent.showNextEvent) + private let nextEventRangeStepperLabel = Label() private let nextEventRangeStepper = NSStepper() + private let nextEventGrabAttentionLabel = Label(text: Strings.Settings.NextEvent.grabAttention) + private let nextEventFlashingCheckbox = Checkbox(title: Strings.Settings.NextEvent.GrabAttention.flashing) + private let nextEventSoundCheckbox = Checkbox(title: Strings.Settings.NextEvent.GrabAttention.sound) // Calendar private let firstWeekdayPrev = ImageButton(image: Icons.Settings.prev) @@ -68,6 +74,7 @@ class GeneralSettingsViewController: NSViewController, SettingsUI { let stackView = NSStackView( views: Sections.create([ makeSection(title: Strings.Settings.menuBar, content: menuBarContent), + makeSection(title: Strings.Settings.nextEvent, content: nextEventContent), makeSection(title: Strings.Settings.calendar, content: calendarContent), makeSection(title: Strings.Settings.events, content: eventsContent), ]) @@ -132,8 +139,7 @@ class GeneralSettingsViewController: NSViewController, SettingsUI { autoLaunchCheckbox, iconStyle, dateFormat, - showMenuBarBackgroundCheckbox, - nextEventContent + showMenuBarBackgroundCheckbox ]) .with(orientation: .vertical) }() @@ -148,28 +154,17 @@ class GeneralSettingsViewController: NSViewController, SettingsUI { nextEventRangeStepper.refusesFirstResponder = true nextEventRangeStepper.focusRingType = .none - let rangeStepperLabel = Label(font: .systemFont(ofSize: 13)) - - let rangeStepperProperty = nextEventRangeStepper.rx.controlProperty( - getter: \.integerValue, - setter: { $0.integerValue = $1 } - ) - - viewModel.eventStatusItemCheckRange - .bind(to: rangeStepperProperty) - .disposed(by: disposeBag) - - rangeStepperProperty - .bind(to: viewModel.eventStatusItemCheckRangeObserver) - .disposed(by: disposeBag) - - viewModel.eventStatusItemCheckRangeLabel - .bind(to: rangeStepperLabel.rx.text) - .disposed(by: disposeBag) + nextEventRangeStepperLabel.font = .systemFont(ofSize: 13) // Next event stack view + let showNextEventStack = NSStackView(views: [showNextEventCheckbox, .spacer, nextEventRangeStepperLabel, nextEventRangeStepper]) + let grabAttentionStack = NSStackView(views: [nextEventFlashingCheckbox, nextEventSoundCheckbox]).with(insets: .init(horizontal: 16)) + return NSStackView(views: [ + showNextEventStack, + nextEventGrabAttentionLabel, + grabAttentionStack - return NSStackView(views: [showNextEventCheckbox, .spacer, rangeStepperLabel, nextEventRangeStepper]) + ]).with(orientation: .vertical) }() private lazy var showDeclinedEventsTooltip: NSView = { @@ -233,6 +228,7 @@ class GeneralSettingsViewController: NSViewController, SettingsUI { private func setUpBindings() { setUpMenuBar() + setUpNextEvent() setUpCalendar() setUpEvents() } @@ -253,6 +249,8 @@ class GeneralSettingsViewController: NSViewController, SettingsUI { ) .disposed(by: disposeBag) + setUpIconStyle() + bind( control: showMenuBarDateCheckbox, observable: viewModel.showStatusItemDate, @@ -260,12 +258,17 @@ class GeneralSettingsViewController: NSViewController, SettingsUI { ) .disposed(by: disposeBag) + setUpDateFormat() + bind( control: showMenuBarBackgroundCheckbox, observable: viewModel.showStatusItemBackground, observer: viewModel.toggleStatusItemBackground ) .disposed(by: disposeBag) + } + + private func setUpNextEvent() { bind( control: showNextEventCheckbox, @@ -274,11 +277,41 @@ class GeneralSettingsViewController: NSViewController, SettingsUI { ) .disposed(by: disposeBag) - setUpIconStyle() + setUpNextEventRangeStepper() - setUpDateFormat() + bind( + control: nextEventFlashingCheckbox, + observable: viewModel.eventStatusItemFlashing, + observer: viewModel.toggleEventStatusItemFlashing + ) + .disposed(by: disposeBag) - setUpCalendarAppViewMode() + bind( + control: nextEventSoundCheckbox, + observable: viewModel.eventStatusItemSound, + observer: viewModel.toggleEventStatusItemSound + ) + .disposed(by: disposeBag) + } + + private func setUpNextEventRangeStepper() { + + let rangeStepperProperty = nextEventRangeStepper.rx.controlProperty( + getter: \.integerValue, + setter: { $0.integerValue = $1 } + ) + + viewModel.eventStatusItemCheckRange + .bind(to: rangeStepperProperty) + .disposed(by: disposeBag) + + rangeStepperProperty + .bind(to: viewModel.eventStatusItemCheckRangeObserver) + .disposed(by: disposeBag) + + viewModel.eventStatusItemCheckRangeLabel + .bind(to: nextEventRangeStepperLabel.rx.text) + .disposed(by: disposeBag) } private func setUpIconStyle() { @@ -436,6 +469,8 @@ class GeneralSettingsViewController: NSViewController, SettingsUI { observer: viewModel.toggleDateHoverOption ) .disposed(by: disposeBag) + + setUpCalendarAppViewMode() } private func setUpfirstWeekday() { diff --git a/Calendr/Settings/Prefs+UserDefaults.swift b/Calendr/Settings/Prefs+UserDefaults.swift index d1282fe..cdb9779 100644 --- a/Calendr/Settings/Prefs+UserDefaults.swift +++ b/Calendr/Settings/Prefs+UserDefaults.swift @@ -22,6 +22,8 @@ enum Prefs { // Next Event static let showEventStatusItem = "show_event_status_item" static let eventStatusItemCheckRange = "event_status_item_check_range" + static let eventStatusItemFlashing = "event_status_item_flashing" + static let eventStatusItemSound = "event_status_item_sound" static let eventStatusItemLength = "event_status_item_length" static let eventStatusItemDetectNotch = "event_status_item_detect_notch" static let eventStatusItemTextScaling = "event_status_item_text_scaling" @@ -74,6 +76,8 @@ func registerDefaultPrefs(in userDefaults: UserDefaults, calendar: Calendar = .c // Next Event Prefs.showEventStatusItem: false, Prefs.eventStatusItemCheckRange: 6, + Prefs.eventStatusItemFlashing: false, + Prefs.eventStatusItemSound: false, Prefs.eventStatusItemTextScaling: 1.2, Prefs.eventStatusItemLength: 18, Prefs.eventStatusItemDetectNotch: false, @@ -167,6 +171,16 @@ extension UserDefaults { set { set(newValue, forKey: Prefs.eventStatusItemCheckRange) } } + @objc dynamic var eventStatusItemFlashing: Bool { + get { bool(forKey: Prefs.eventStatusItemFlashing) } + set { set(newValue, forKey: Prefs.eventStatusItemFlashing) } + } + + @objc dynamic var eventStatusItemSound: Bool { + get { bool(forKey: Prefs.eventStatusItemSound) } + set { set(newValue, forKey: Prefs.eventStatusItemSound) } + } + @objc dynamic var eventStatusItemTextScaling: Double { get { double(forKey: Prefs.eventStatusItemTextScaling) } set { set(newValue, forKey: Prefs.eventStatusItemTextScaling) } diff --git a/Calendr/Settings/SettingsViewModel.swift b/Calendr/Settings/SettingsViewModel.swift index fe0e442..ba18149 100644 --- a/Calendr/Settings/SettingsViewModel.swift +++ b/Calendr/Settings/SettingsViewModel.swift @@ -88,6 +88,8 @@ protocol EventListSettings: EventSettings { protocol NextEventSettings: EventDetailsSettings { var showEventStatusItem: Observable { get } var eventStatusItemCheckRange: Observable { get } + var eventStatusItemFlashing: Observable { get } + var eventStatusItemSound: Observable { get } var eventStatusItemTextScaling: Observable { get } var eventStatusItemLength: Observable { get } var eventStatusItemDetectNotch: Observable { get } @@ -123,8 +125,10 @@ class SettingsViewModel: let statusItemDateStyleObserver: AnyObserver let statusItemDateFormatObserver: AnyObserver let toggleEventStatusItem: AnyObserver - let eventStatusItemTextScalingObserver: AnyObserver let eventStatusItemCheckRangeObserver: AnyObserver + let toggleEventStatusItemFlashing: AnyObserver + let toggleEventStatusItemSound: AnyObserver + let eventStatusItemTextScalingObserver: AnyObserver let eventStatusItemLengthObserver: AnyObserver let toggleEventStatusItemDetectNotch: AnyObserver let calendarScalingObserver: AnyObserver @@ -157,9 +161,11 @@ class SettingsViewModel: let isDateFormatInputVisible: Observable let showEventStatusItem: Observable let statusItemTextScaling: Observable - let eventStatusItemTextScaling: Observable let eventStatusItemCheckRange: Observable let eventStatusItemCheckRangeLabel: Observable + let eventStatusItemFlashing: Observable + let eventStatusItemSound: Observable + let eventStatusItemTextScaling: Observable let eventStatusItemLength: Observable let eventStatusItemDetectNotch: Observable let calendarScaling: Observable @@ -240,8 +246,10 @@ class SettingsViewModel: statusItemDateFormatObserver = userDefaults.rx.observer(for: \.statusItemDateFormat) toggleEventStatusItem = userDefaults.rx.observer(for: \.showEventStatusItem) statusItemTextScalingObserver = userDefaults.rx.observer(for: \.statusItemTextScaling) - eventStatusItemTextScalingObserver = userDefaults.rx.observer(for: \.eventStatusItemTextScaling) eventStatusItemCheckRangeObserver = userDefaults.rx.observer(for: \.eventStatusItemCheckRange) + toggleEventStatusItemFlashing = userDefaults.rx.observer(for: \.eventStatusItemFlashing) + toggleEventStatusItemSound = userDefaults.rx.observer(for: \.eventStatusItemSound) + eventStatusItemTextScalingObserver = userDefaults.rx.observer(for: \.eventStatusItemTextScaling) eventStatusItemLengthObserver = userDefaults.rx.observer(for: \.eventStatusItemLength) toggleEventStatusItemDetectNotch = userDefaults.rx.observer(for: \.eventStatusItemDetectNotch) calendarScalingObserver = userDefaults.rx.observer(for: \.calendarScaling) @@ -284,8 +292,10 @@ class SettingsViewModel: statusItemDateFormat = userDefaults.rx.observe(\.statusItemDateFormat) showEventStatusItem = userDefaults.rx.observe(\.showEventStatusItem) statusItemTextScaling = userDefaults.rx.observe(\.statusItemTextScaling) - eventStatusItemTextScaling = userDefaults.rx.observe(\.eventStatusItemTextScaling) eventStatusItemCheckRange = userDefaults.rx.observe(\.eventStatusItemCheckRange) + eventStatusItemFlashing = userDefaults.rx.observe(\.eventStatusItemFlashing) + eventStatusItemSound = userDefaults.rx.observe(\.eventStatusItemSound) + eventStatusItemTextScaling = userDefaults.rx.observe(\.eventStatusItemTextScaling) eventStatusItemLength = userDefaults.rx.observe(\.eventStatusItemLength) eventStatusItemDetectNotch = userDefaults.rx.observe(\.eventStatusItemDetectNotch) calendarScaling = userDefaults.rx.observe(\.calendarScaling) diff --git a/CalendrTests/Mocks/MockNextEventSettings.swift b/CalendrTests/Mocks/MockNextEventSettings.swift index 3e73cc6..989dd07 100644 --- a/CalendrTests/Mocks/MockNextEventSettings.swift +++ b/CalendrTests/Mocks/MockNextEventSettings.swift @@ -13,12 +13,15 @@ class MockNextEventSettings: MockEventDetailsSettings, NextEventSettings { let toggleStatusItem: AnyObserver let showEventStatusItem: Observable - let eventStatusItemFontSizeObserver: AnyObserver - let eventStatusItemFontSize: Observable - let eventStatusItemCheckRangeObserver: AnyObserver let eventStatusItemCheckRange: Observable + let toggleEventStatusItemFlashing: AnyObserver + let eventStatusItemFlashing: Observable + + let toggleEventStatusItemSound: AnyObserver + let eventStatusItemSound: Observable + let eventStatusItemLengthObserver: AnyObserver let eventStatusItemLength: Observable @@ -29,8 +32,9 @@ class MockNextEventSettings: MockEventDetailsSettings, NextEventSettings { init() { (showEventStatusItem, toggleStatusItem) = BehaviorSubject.pipe(value: true) - (eventStatusItemFontSize, eventStatusItemFontSizeObserver) = BehaviorSubject.pipe(value: 12) (eventStatusItemCheckRange, eventStatusItemCheckRangeObserver) = BehaviorSubject.pipe(value: 18) + (eventStatusItemFlashing, toggleEventStatusItemFlashing) = BehaviorSubject.pipe(value: false) + (eventStatusItemSound, toggleEventStatusItemSound) = BehaviorSubject.pipe(value: false) (eventStatusItemLength, eventStatusItemLengthObserver) = BehaviorSubject.pipe(value: 18) (eventStatusItemDetectNotch, toggleEventStatusItemDetectNotch) = BehaviorSubject.pipe(value: false) eventStatusItemTextScaling = .just(1) diff --git a/MISSING_TRANSLATIONS.md b/MISSING_TRANSLATIONS.md index 6b32d05..78a0b34 100644 --- a/MISSING_TRANSLATIONS.md +++ b/MISSING_TRANSLATIONS.md @@ -1,13 +1,15 @@ # The following languages have missing translations Language|Count -|- -[Chinese - 中文 - (zh-Hant-TW)](Calendr/Assets/zh-Hant-TW.lproj/Localizable.strings)|1 -[Chinese - 中文 - (zh-Hans)](Calendr/Assets/zh-Hans.lproj/Localizable.strings)|1 -[Spanish - español - (es)](Calendr/Assets/es.lproj/Localizable.strings)|11 -[Italian - italiano - (it)](Calendr/Assets/it.lproj/Localizable.strings)|1 -[Swedish - svenska - (sv)](Calendr/Assets/sv.lproj/Localizable.strings)|26 -[Czech - čeština - (cs)](Calendr/Assets/cs.lproj/Localizable.strings)|26 -[French - français - (fr)](Calendr/Assets/fr.lproj/Localizable.strings)|1 +[German - Deutsch - (de)](Calendr/Assets/de.lproj/Localizable.strings)|3 +[Chinese - 中文 - (zh-Hant-TW)](Calendr/Assets/zh-Hant-TW.lproj/Localizable.strings)|4 +[Chinese - 中文 - (zh-Hans)](Calendr/Assets/zh-Hans.lproj/Localizable.strings)|4 +[Spanish - español - (es)](Calendr/Assets/es.lproj/Localizable.strings)|14 +[Italian - italiano - (it)](Calendr/Assets/it.lproj/Localizable.strings)|4 +[Slovak - slovenčina - (sk)](Calendr/Assets/sk.lproj/Localizable.strings)|3 +[Swedish - svenska - (sv)](Calendr/Assets/sv.lproj/Localizable.strings)|29 +[Czech - čeština - (cs)](Calendr/Assets/cs.lproj/Localizable.strings)|29 +[French - français - (fr)](Calendr/Assets/fr.lproj/Localizable.strings)|4 Feel free to open a new issue or pull request with the missing values.