diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..af2ac59 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: 💬 Questions & ideas + url: https://github.com/SKemenov/MinimalCountdown/discussions + about: Ask a question or share an idea in Discussions + - name: ℹ️ About Minimal Countdown + url: https://github.com/SKemenov/MinimalCountdown + about: Features, screenshots, and install guide in the README diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7..448ac88 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,8 +1,8 @@ --- -name: Feature request +name: "\U0001F4A1 Feature request" about: Suggest an idea for this project -title: '' -labels: '' +title: "[FR] " +labels: enhancement assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/macos-bug-report.md b/.github/ISSUE_TEMPLATE/macos-bug-report.md index 3ad5814..02ad2ae 100644 --- a/.github/ISSUE_TEMPLATE/macos-bug-report.md +++ b/.github/ISSUE_TEMPLATE/macos-bug-report.md @@ -1,8 +1,8 @@ --- -name: MacOS Bug report +name: "\U0001FAB2 Bug report" about: Create a report to help us improve title: "[BUG] " -labels: '' +labels: bug assignees: '' --- diff --git a/.gitignore b/.gitignore index f015fa3..4abbf44 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ /.build /Packages xcuserdata/ -DerivedData/ \ No newline at end of file +DerivedData/ + +# Local release staging (published to GitHub Releases, not committed) +/Releases \ No newline at end of file diff --git a/MinimalCountdown.xcodeproj/project.pbxproj b/MinimalCountdown.xcodeproj/project.pbxproj index b3eacc5..e6d3d07 100644 --- a/MinimalCountdown.xcodeproj/project.pbxproj +++ b/MinimalCountdown.xcodeproj/project.pbxproj @@ -70,6 +70,7 @@ Persistence/Stores/MigratingLoader.swift, Persistence/Stores/MockInMemoryLocalStore.swift, Resources/Assets.xcassets, + Resources/InfoPlist.xcstrings, Resources/Localizable.xcstrings, Resources/Resources.swift, Views/Countdown/CountdownView.swift, @@ -421,6 +422,8 @@ ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "Minimal Countdown"; SDKROOT = macosx; + SHARED_BUILD_NUMBER = 26; + SHARED_VERSION_NUMBER = 2.0.0; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_EMIT_LOC_STRINGS = YES; }; @@ -481,6 +484,8 @@ MTL_FAST_MATH = YES; PRODUCT_NAME = "Minimal Countdown"; SDKROOT = macosx; + SHARED_BUILD_NUMBER = 26; + SHARED_VERSION_NUMBER = 2.0.0; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_EMIT_LOC_STRINGS = YES; @@ -494,7 +499,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = "$(SHARED_BUILD_NUMBER)"; DEAD_CODE_STRIPPING = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = MinimalCountdown/Info.plist; @@ -505,7 +510,7 @@ INFOPLIST_KEY_NSPrincipalClass = MinimalCountdown.MinimalCountdownView; INSTALL_PATH = "$(HOME)/Library/Screen Savers"; MACOSX_DEPLOYMENT_TARGET = 14.6; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = "$(SHARED_VERSION_NUMBER)"; PRODUCT_BUNDLE_IDENTIFIER = com.skemenov.MinimalCountdown; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -522,7 +527,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = "$(SHARED_BUILD_NUMBER)"; DEAD_CODE_STRIPPING = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = MinimalCountdown/Info.plist; @@ -533,7 +538,7 @@ INFOPLIST_KEY_NSPrincipalClass = MinimalCountdown.MinimalCountdownView; INSTALL_PATH = "$(HOME)/Library/Screen Savers"; MACOSX_DEPLOYMENT_TARGET = 14.6; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = "$(SHARED_VERSION_NUMBER)"; PRODUCT_BUNDLE_IDENTIFIER = com.skemenov.MinimalCountdown; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -549,7 +554,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = "$(SHARED_BUILD_NUMBER)"; DEAD_CODE_STRIPPING = YES; ENABLE_APP_SANDBOX = NO; ENABLE_HARDENED_RUNTIME = NO; @@ -561,7 +566,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 26.4; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = "$(SHARED_VERSION_NUMBER)"; PRODUCT_BUNDLE_IDENTIFIER = com.skemenov.MinimalDevApp; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES; @@ -581,7 +586,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = "$(SHARED_BUILD_NUMBER)"; DEAD_CODE_STRIPPING = YES; ENABLE_APP_SANDBOX = NO; ENABLE_HARDENED_RUNTIME = NO; @@ -593,7 +598,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 26.4; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = "$(SHARED_VERSION_NUMBER)"; PRODUCT_BUNDLE_IDENTIFIER = com.skemenov.MinimalDevApp; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES; @@ -610,11 +615,11 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = "$(SHARED_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 3LKWW87KA9; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 26.5; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = "$(SHARED_VERSION_NUMBER)"; PRODUCT_BUNDLE_IDENTIFIER = com.skemenov.MinimalDevAppTests; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = NO; @@ -633,11 +638,11 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = "$(SHARED_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 3LKWW87KA9; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 26.5; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = "$(SHARED_VERSION_NUMBER)"; PRODUCT_BUNDLE_IDENTIFIER = com.skemenov.MinimalDevAppTests; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = NO; diff --git a/MinimalCountdown/Resources/InfoPlist.xcstrings b/MinimalCountdown/Resources/InfoPlist.xcstrings new file mode 100644 index 0000000..aacb543 --- /dev/null +++ b/MinimalCountdown/Resources/InfoPlist.xcstrings @@ -0,0 +1,45 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "CFBundleDisplayName" : { + "comment" : "Bundle display name — keep 'Minimal Countdown' (with space) in every language.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Minimal Countdown" + } + } + }, + "shouldTranslate" : false + }, + "CFBundleName" : { + "comment" : "Bundle name shown in System Settings — keep 'Minimal Countdown' (with space) in every language.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Minimal Countdown" + } + } + }, + "shouldTranslate" : false + }, + "NSHumanReadableCopyright" : { + "comment" : "Copyright (human-readable)", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "" + } + } + }, + "shouldTranslate" : false + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/MinimalDevApp/Previews/ScreenshotPreviews.swift b/MinimalDevApp/Previews/ScreenshotPreviews.swift new file mode 100644 index 0000000..37c2162 --- /dev/null +++ b/MinimalDevApp/Previews/ScreenshotPreviews.swift @@ -0,0 +1,73 @@ +// +// ScreenshotPreviews.swift +// MinimalDevApp +// +// Created by Sergey Kemenov +// + +// README screenshot sources. Render each #Preview (Xcode canvas or RenderPreview), +// then crop the window title bar for the full-bleed countdown shots. Filenames map to +// vendors/mc-screenshot-*.png. +// Use Figma to generate final images: +// https://www.figma.com/design/7f6nLbnA7hD8v6c6GrlwWh/Screensaver-Mockups + +#if DEBUG +import SwiftUI + +// vendors/mc-screenshot-01s — classic, all units, default look +#Preview("Classic") { + CountdownWindow(now: Date(), settings: .default, isPreview: true) + .frame(width: 1024, height: 730) +} + +// vendors/mc-screenshot-02s — days-only, cyan, with a message +#Preview("Cyan — days only") { + CountdownWindow( + now: Date(), + settings: SaverSettings( + appearance: .init(style: .days, isLabelHidden: false), + schedule: .init(target: Date(timeIntervalSinceNow: 26 * 86400 + 3600)), + theme: .init(accent: .cyan, background: .black, brightness: .high, effect: .none, effectColor: .cyan), + typography: .init(weight: .bold, isRounded: false, numeralSystem: .automatic), + language: .automatic, + title: .init(text: "See you soon", isHidden: false) + ), + isPreview: true + ) + .frame(width: 1024, height: 730) +} + +// vendors/mc-screenshot-03s — amber glow with a title +#Preview("Amber glow") { + CountdownWindow( + now: Date(), + settings: SaverSettings( + appearance: .init(style: .seconds, isLabelHidden: false), + schedule: .init(target: Date(timeIntervalSinceNow: 2 * 86400 + 16 * 3600 + 27 * 60 + 2)), + theme: .init(accent: .yellow, background: .black, brightness: .high, effect: .glow, effectColor: .yellow), + typography: .init(weight: .ultraLight, isRounded: false, numeralSystem: .automatic), + language: .automatic, + title: .init(text: "WWDC", isHidden: false) + ), + isPreview: true + ) + .frame(width: 1024, height: 730) +} + +// vendors/mc-screenshot-04s — backlight effect, bold rounded digits, pink +#Preview("Pink — backlight") { + CountdownWindow( + now: Date(), + settings: SaverSettings( + appearance: .init(style: .seconds, isLabelHidden: false), + schedule: .init(target: Date(timeIntervalSinceNow: 7 * 86400 + 3600)), + theme: .init(accent: .pink, background: .black, brightness: .high, effect: .backlight, effectColor: .pink), + typography: .init(weight: .bold, isRounded: true, numeralSystem: .automatic), + language: .automatic, + title: .init(text: "", isHidden: true) + ), + isPreview: false + ) + .frame(width: 1024, height: 730) +} +#endif diff --git a/README.md b/README.md index 9c8345d..4a436dd 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,43 @@ -## Minimal Countdown screensaver (macOS) v1.1 +## Minimal Countdown screensaver (macOS) v2.0.0 -Minimal Countdown is a minimalistic countdown screen saver for macOS. Shows the timer while you take a rest for a while. +Minimal Countdown is a minimalistic countdown screen saver for macOS. It counts down to — or up from — a date you choose, ticking quietly while your Mac rests. Last release notes [read here](https://github.com/SKemenov/MinimalCountdown/releases).

- + + -

## Features -- [x] Use `Options...` to customize the screen saver -- [x] Set the date and time for your timer (if the date is in the past, the timer increases) -- [x] Add a short message to display above the timer -- [x] Show or hide the message -- [x] Change text color -- [x] Dim the color if you like -- [x] Select a style for your timer to display days, hours, minutes and even seconds -- [x] Localization - English +- [x] The totally redesigned Settings window, opened from `Options…`, allows you to customize the screensaver as you want +- [x] The screensaver's now using a separate file to store its settings; you may duplicate it across multiple Macs. +- [x] Set the target date and time — counts down to a future date, counts up from a past one (Stopwatch mode), and switches to Stopwatch automatically when it reaches zero +- [x] The date range has been extended to more than two years (actually, up to 999 days before or after today) +- [x] Add a short title above the timer, you may also show or hide it +- [x] Choose what to show — days, hours, minutes, and seconds — and optionally hide the unit labels as well +- [x] Use one of 11 accent colors for the screensaver +- [x] Three brightness levels to dim the digits to taste +- [x] Apply new digit effects — `blur`, `inner glow`, `backlight`, or `glow` — with a custom effect color or select `none` if you prefer classic +- [x] Adjust the digit font weight and switch to rounded digits +- [x] Choose a numeral system (Western, Eastern Arabic, and more) +- [x] Localized in 10 languages — English, Spanish, German, French, Russian, Hebrew, Arabic, Persian, Hindi, and Sanskrit +- [x] The settings window supports right-to-left localized languages ## Compatibility -Minimal Countdowns screen saver requires OS X Ventura or later. +Minimal Countdown requires macOS Sonoma or later. ## Stack -`Swift only`, `no storyboards`, `AppKit`, `ScreenSaver`, `ScreenSaverDefaults` +`Swift`, `SwiftUI`, `ScreenSaver`, `Swift Testing` ## Downloads -### [Minimal Countdown Screen Saver (.zip)](https://github.com/SKemenov/MinimalCountdown/releases/download/1.1/MinimalCountdown.saver.zip) +### [Latest release →](https://github.com/SKemenov/MinimalCountdown/releases/latest) ## How to install 1. Unzip and install it (now without any Gatekeeper warnings) @@ -42,14 +47,14 @@ Minimal Countdowns screen saver requires OS X Ventura or later. ## Configurations

- +

## How to re-install 1. Open `System Settings` → `Wallpaper` → `Screen Saver…` button (macOS Tahoe) - or `System Settings` → `Screen Saver` (macOS Ventura–Sequoia) -2. Right-click MinimalCountdown → `Delete "MinimalCountdown"` → `Move to Trash` + or `System Settings` → `Screen Saver` (macOS Sonoma–Sequoia) +2. Right-click Minimal Countdown → `Delete "Minimal Countdown"` → `Move to Trash` 3. Close `System Settings` 4. Run `killall WallpaperAgent` in Terminal (or just restart your computer) 5. Install the new version of `MinimalCountdown.saver` @@ -58,8 +63,8 @@ Minimal Countdowns screen saver requires OS X Ventura or later. ## I appreciate your ideas! -- [Sam Soffes](https://github.com/soffes/Countdown) - [Aerial](https://github.com/AerialScreensaver/ScreenSaverMinimal) - [Mirko Fetter](https://github.com/mirkofetter/ScreenSaverMinimal/tree/master) - [Eskil Gjerde Sviggum](https://github.com/Eskils/JellyfishSaver) +- [Sam Soffes](https://github.com/soffes/Countdown) - `Apple docs`, `stack overflow` and `medium`. diff --git a/vendors/configurations.png b/vendors/configurations.png deleted file mode 100644 index 9ed6170..0000000 Binary files a/vendors/configurations.png and /dev/null differ diff --git a/vendors/mc-screenshot-01s.png b/vendors/mc-screenshot-01s.png index f74073b..d567be3 100644 Binary files a/vendors/mc-screenshot-01s.png and b/vendors/mc-screenshot-01s.png differ diff --git a/vendors/mc-screenshot-02s.png b/vendors/mc-screenshot-02s.png index 5b20366..0d607e0 100644 Binary files a/vendors/mc-screenshot-02s.png and b/vendors/mc-screenshot-02s.png differ diff --git a/vendors/mc-screenshot-03s.png b/vendors/mc-screenshot-03s.png index f1b20d8..c647f67 100644 Binary files a/vendors/mc-screenshot-03s.png and b/vendors/mc-screenshot-03s.png differ diff --git a/vendors/mc-screenshot-04s.png b/vendors/mc-screenshot-04s.png index 0784d44..4e53b6d 100644 Binary files a/vendors/mc-screenshot-04s.png and b/vendors/mc-screenshot-04s.png differ diff --git a/vendors/mc-screenshot-05s.png b/vendors/mc-screenshot-05s.png index 39dc9a0..6b9b3f2 100644 Binary files a/vendors/mc-screenshot-05s.png and b/vendors/mc-screenshot-05s.png differ diff --git a/vendors/screenshot.png b/vendors/screenshot.png deleted file mode 100644 index aa08a66..0000000 Binary files a/vendors/screenshot.png and /dev/null differ