├── .gitignore
├── .vscode
└── tasks.json
├── LICENSE.md
├── Makefile
├── README.md
├── SleeperCore.plist
├── SleeperCoreLegacy.plist
├── SleeperUI.plist
├── assets
├── 1.png
├── 2.png
├── 3.png
├── 4.png
├── 5.png
├── banner.png
├── banner.psd
├── icon.png
├── icon.psd
├── noun_Alarm Clock_2891329.png
├── noun_Arrow Share_1624620.png
├── noun_Night_602944.png
└── open_in-highres.png
├── build_release.sh
├── common
├── SLAlarmPrefs.h
├── SLAlarmPrefs.m
├── SLAutoSetManager.h
├── SLAutoSetManager.m
├── SLCommonHeaders.h
├── SLCompatibilityHelper.h
├── SLCompatibilityHelper.m
├── SLLocalizedStrings.h
├── SLPrefsManager.h
├── SLPrefsManager.m
├── SLSkipAlarmAlertItem.h
├── SLSkipAlarmAlertItem.xm
└── SLSpringBoard.x
├── control
├── control_BigBoss
├── control_Havoc
├── core
├── SLMTAlarm.x
├── SLMTAlarmManager.x
├── SLMTAlarmStorage.x
├── SLMTUserNotificationCenter.x
├── SLSBDashBoardLockScreenEnvironment.x
└── SLSBLockScreenViewControllerBase.x
├── core_legacy
├── SLAlarmManager.x
├── SLSBApplication.x
├── SLSBClockDataProvider.x
├── SLSBLockScreenManager.x
├── SLSBLockScreenViewController.x
├── SLSBLockScreenViewControllerBase.x
├── SLUNLocalNotificationClient.x
└── SLUNSNotificationSchedulingService.x
├── holiday_gen.py
├── layout
├── DEBIAN
│ ├── postinst
│ └── postrm
└── Library
│ └── Application Support
│ └── Sleeper.bundle
│ ├── ar.lproj
│ └── Localizable.strings
│ ├── ar_holidays.plist
│ ├── at_holidays.plist
│ ├── au_holidays.plist
│ ├── aw_holidays.plist
│ ├── be_holidays.plist
│ ├── bg_holidays.plist
│ ├── br_holidays.plist
│ ├── by_holidays.plist
│ ├── ca.lproj
│ └── Localizable.strings
│ ├── ca_holidays.plist
│ ├── ch_holidays.plist
│ ├── checkmark.png
│ ├── checkmark@2x.png
│ ├── checkmark@3x.png
│ ├── cn_holidays.plist
│ ├── co_holidays.plist
│ ├── cs.lproj
│ └── Localizable.strings
│ ├── cz_holidays.plist
│ ├── da.lproj
│ └── Localizable.strings
│ ├── de.lproj
│ └── Localizable.strings
│ ├── de_holidays.plist
│ ├── dk_holidays.plist
│ ├── do_holidays.plist
│ ├── ee_holidays.plist
│ ├── eg_holidays.plist
│ ├── el.lproj
│ └── Localizable.strings
│ ├── en.lproj
│ └── Localizable.strings
│ ├── es.lproj
│ └── Localizable.strings
│ ├── es_holidays.plist
│ ├── fi.lproj
│ └── Localizable.strings
│ ├── fi_holidays.plist
│ ├── fr.lproj
│ └── Localizable.strings
│ ├── fra_holidays.plist
│ ├── he.lproj
│ └── Localizable.strings
│ ├── hk_holidays.plist
│ ├── hr_holidays.plist
│ ├── hu.lproj
│ └── Localizable.strings
│ ├── hu_holidays.plist
│ ├── icon.png
│ ├── id.lproj
│ └── Localizable.strings
│ ├── ie_holidays.plist
│ ├── il_holidays.plist
│ ├── ind_holidays.plist
│ ├── is_holidays.plist
│ ├── it.lproj
│ └── Localizable.strings
│ ├── it_holidays.plist
│ ├── ja.lproj
│ └── Localizable.strings
│ ├── jp_holidays.plist
│ ├── ke_holidays.plist
│ ├── ko.lproj
│ └── Localizable.strings
│ ├── kr_holidays.plist
│ ├── la.lproj
│ └── Localizable.strings
│ ├── lt_holidays.plist
│ ├── lu_holidays.plist
│ ├── ma_holidays.plist
│ ├── ms.lproj
│ └── Localizable.strings
│ ├── mx_holidays.plist
│ ├── nb.lproj
│ └── Localizable.strings
│ ├── ng_holidays.plist
│ ├── ni_holidays.plist
│ ├── nl.lproj
│ └── Localizable.strings
│ ├── nl_holidays.plist
│ ├── no_holidays.plist
│ ├── nz_holidays.plist
│ ├── open_in.png
│ ├── open_in@2x.png
│ ├── open_in@3x.png
│ ├── pe_holidays.plist
│ ├── pl.lproj
│ └── Localizable.strings
│ ├── pl_holidays.plist
│ ├── pt.lproj
│ └── Localizable.strings
│ ├── pt_PT.lproj
│ └── Localizable.strings
│ ├── pt_holidays.plist
│ ├── py_holidays.plist
│ ├── ro.lproj
│ └── Localizable.strings
│ ├── rs_holidays.plist
│ ├── ru.lproj
│ └── Localizable.strings
│ ├── ru_holidays.plist
│ ├── se_holidays.plist
│ ├── sg_holidays.plist
│ ├── si_holidays.plist
│ ├── sk_holidays.plist
│ ├── sv.lproj
│ └── Localizable.strings
│ ├── tr.lproj
│ └── Localizable.strings
│ ├── tr_holidays.plist
│ ├── tw_holidays.plist
│ ├── ua_holidays.plist
│ ├── uk_holidays.plist
│ ├── us_holidays.plist
│ ├── vi.lproj
│ └── Localizable.strings
│ ├── vn_holidays.plist
│ ├── za_holidays.plist
│ ├── zh_CN.lproj
│ └── Localizable.strings
│ └── zh_TW.lproj
│ └── Localizable.strings
├── localized_helper.py
└── ui
├── SLEditAlarmViewController.xm
├── SLHKSHQuickScheduleOverrideViewController.xm
├── SLMTAAlarmEditViewController.xm
├── SLMTABedtimeOptionsViewController.x
├── SLMTABedtimeViewController.x
├── SLMTASleepDetailViewController.x
├── SLMTASleepOptionsViewController.x
├── SLMTSleepAlarmOptionsController.x
├── SLMTSleepAlarmViewController.x
├── SLUserInterfaceHeaders.h
└── custom
├── SLAutoSetOptionsTableViewController.h
├── SLAutoSetOptionsTableViewController.m
├── SLEditDateTimeViewController.h
├── SLEditDateTimeViewController.m
├── SLHolidaySelectionTableViewController.h
├── SLHolidaySelectionTableViewController.m
├── SLPartialModalPresentationController.h
├── SLPartialModalPresentationController.m
├── SLPickerTableViewController.h
├── SLPickerTableViewController.m
├── SLSkipDatesViewController.h
├── SLSkipDatesViewController.m
├── SLSkipTimeViewController.h
├── SLSkipTimeViewController.m
├── SLSnoozeTimeViewController.h
└── SLSnoozeTimeViewController.m
/.gitignore:
--------------------------------------------------------------------------------
1 | .theos
2 | .DS_Store
3 | packages
4 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "label": "install",
8 | "type": "shell",
9 | "command": "make package install",
10 | "group": "build",
11 | "problemMatcher": []
12 | },
13 | {
14 | "label": "build",
15 | "type": "shell",
16 | "command": "make package",
17 | "group": {
18 | "kind": "build",
19 | "isDefault": true
20 | },
21 | "problemMatcher": []
22 | },
23 | {
24 | "label": "clean",
25 | "type": "shell",
26 | "command": "make clean",
27 | "group": "build",
28 | "problemMatcher": []
29 | }
30 | ]
31 | }
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | TARGET=iphone:clang:14.5:8.0
2 | ARCHS=armv7 arm64 arm64e
3 |
4 | PACKAGE_VERSION=$(THEOS_PACKAGE_BASE_VERSION)
5 |
6 | include $(THEOS)/makefiles/common.mk
7 |
8 | LIBRARY_NAME = libSleeper
9 | TWEAK_NAME = SleeperCore SleeperCoreLegacy SleeperUI
10 |
11 | libSleeper_FILES = $(wildcard common/*.m) $(wildcard common/*.xm ) $(wildcard common/*.x)
12 | libSleeper_PRIVATE_FRAMEWORKS = MobileTimer
13 | libSleeper_OBJCFLAGS = -fobjc-arc
14 | libSleeper_LDFLAGS = -lsubstrate
15 |
16 | SleeperCore_FILES = $(wildcard core/*.x)
17 | SleeperCore_LIBRARIES = Sleeper
18 | SleeperCore_OBJCFLAGS = -fobjc-arc
19 | SleeperCore_LDFLAGS = -L$(THEOS_OBJ_DIR)
20 |
21 | SleeperCoreLegacy_FILES = $(wildcard core_legacy/*.x)
22 | SleeperCoreLegacy_LIBRARIES = Sleeper
23 | SleeperCoreLegacy_OBJCFLAGS = -fobjc-arc
24 | SleeperCoreLegacy_LDFLAGS = -L$(THEOS_OBJ_DIR)
25 |
26 | SleeperUI_FILES = $(wildcard ui/*.x) $(wildcard ui/*.xm) $(wildcard ui/custom/*.m)
27 | SleeperUI_LIBRARIES = Sleeper
28 | SleeperUI_OBJCFLAGS = -fobjc-arc
29 | SleeperUI_LDFLAGS = -L$(THEOS_OBJ_DIR)
30 |
31 | include $(THEOS_MAKE_PATH)/library.mk
32 | include $(THEOS_MAKE_PATH)/tweak.mk
33 |
34 | after-install::
35 | install.exec "killall -9 MobileTimer; killall -9 mobiletimerd; killall -9 SpringBoard;"
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **This package is for iOS 8 - iOS 14 jailbreaks. For iOS 15+ and rootless jailbreak compatibility, please see [SleeperX](https://havoc.app/package/sleeperx).**
2 |
3 | Sleeper is a tweak designed to give you more functionality around your stock iOS alarms. The goal of Sleeper is to allow you to sleep more using the stock iOS alarms.
4 |
5 | * Change the snooze time of the alarm
6 | * Using a system prompt upon unlocking the device, optionally skip an alarm within a particular set time
7 | * Skip an alarm completely by specifying a specific date or holiday
8 | * Auto-set: Configure alarms to automatically update based on the sunrise or sunset time
9 | * Supports both standalone alarms as well as the Bedtime Alarm introduced with iOS 10
10 | * Compatible with iOS 8 - iOS 14 (note: the auto-set feature is only supported on iOS 10+)
11 | * Compatible with iPhones, iPads, and iPod Touches
12 |
13 | ## *Snooze Time*
14 |
15 | Editing or creating a new alarm will now show a new option: Snooze Time. Entering this view will allow you specify the hours, minutes, and seconds you'd like your alarm to perform the snooze. This interface was designed to integrate seamlessly with the stock iOS Clock application.
16 |
17 | ## *Skipping*
18 |
19 | Use the Skip Toggle to enable or disable the ability to skip the particular alarm. Skipping an alarm can be achieved via a prompt that is displayed upon unlocking the device within a specific period of time or by specifying a particular date/holiday to skip.
20 |
21 | **Skip Time**
22 |
23 | Skip Time is the threshold that is used to determine if you will be prompted to skip the given alarm. The prompt to skip an eligible alarm will show up after unlocking the device. As an example, if you have an alarm set to go off at 8:00am and your Skip Time is 30 minutes, then if you unlock the device between 7:30am and 8:00am, you will be asked if you'd like to skip that alarm. Only one prompt will be shown each time the device is unlocked; the earliest alarm that can be skipped is what will be shown. This feature can be very useful if you frequently find yourself waking up before an alarm is going to go off.
24 |
25 | **Skip Dates / Away Dates**
26 |
27 | The Skip Dates interface allows you to pick specific dates and/or holidays in which the particular alarm will be completely skipped/silenced. Know you'll be taking a vacation or a day off from work? Add that date to your alarm so you can sleep in on those days. Do you work on Thanksgiving or Christmas? Probably not, so be sure to add those holidays to the selected holidays for your alarm. This prevents you from having to remember to turn off an alarm when you don't need to wake up early.
28 |
29 | ## *Auto-Set (iOS 10+)*
30 |
31 | You can use the auto-set feature to automatically update alarms based on the sunrise/sunset times. To use this feature, please ensure that you have the Weather application installed with a valid location set. Once enabled, the alarms will automatically update periodically to adjust to the sunrise/sunset times based on the first location you configured in the Weather application.
32 |
33 | ## *Source Code*
34 |
35 | [This project is open source.](https://github.com/joshuaseltzer/Sleeper)
--------------------------------------------------------------------------------
/SleeperCore.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Filter
6 |
7 | Bundles
8 |
9 | com.apple.springboard
10 | com.apple.mobiletimer
11 |
12 | Executables
13 |
14 | mobiletimerd
15 |
16 | CoreFoundationVersion
17 |
18 | 1500
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SleeperCoreLegacy.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Filter
6 |
7 | Bundles
8 |
9 | com.apple.springboard
10 | com.apple.mobiletimer
11 |
12 | CoreFoundationVersion
13 |
14 | 1100
15 | 1400
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/SleeperUI.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Filter
6 |
7 | Bundles
8 |
9 | com.apple.mobiletimer
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/assets/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/1.png
--------------------------------------------------------------------------------
/assets/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/2.png
--------------------------------------------------------------------------------
/assets/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/3.png
--------------------------------------------------------------------------------
/assets/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/4.png
--------------------------------------------------------------------------------
/assets/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/5.png
--------------------------------------------------------------------------------
/assets/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/banner.png
--------------------------------------------------------------------------------
/assets/banner.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/banner.psd
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/icon.png
--------------------------------------------------------------------------------
/assets/icon.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/icon.psd
--------------------------------------------------------------------------------
/assets/noun_Alarm Clock_2891329.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/noun_Alarm Clock_2891329.png
--------------------------------------------------------------------------------
/assets/noun_Arrow Share_1624620.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/noun_Arrow Share_1624620.png
--------------------------------------------------------------------------------
/assets/noun_Night_602944.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/noun_Night_602944.png
--------------------------------------------------------------------------------
/assets/open_in-highres.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/assets/open_in-highres.png
--------------------------------------------------------------------------------
/build_release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # use the Xcode 11 toolchain to ensure arm64e compatibility on iOS 12 and iOS 13
4 | export PREFIX=$THEOS/toolchain/Xcode11.xctoolchain/usr/bin/
5 |
6 | # move the default development and Havoc control files temporarily
7 | mv -n control control_dev
8 | mv -n control_Havoc control
9 |
10 | # build the Havoc package
11 | make clean
12 | make package FINALPACKAGE=1
13 |
14 | # return the Havoc control file to the original name, and prep the BigBoss control file for build
15 | mv -n control control_Havoc
16 | mv -n control_BigBoss control
17 |
18 | # build the BigBoss package
19 | make clean
20 | make package FINALPACKAGE=1
21 |
22 | # return the BigBoss and development control files back to their original states
23 | mv -n control control_BigBoss
24 | mv -n control_dev control
--------------------------------------------------------------------------------
/common/SLAlarmPrefs.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLAlarmPrefs.h
3 | // Object which includes Sleeper preferences for a specific alarm.
4 | //
5 | // Created by Joshua Seltzer on 2/21/17.
6 | //
7 | //
8 |
9 | #import
10 |
11 | // enum that defines the rows countries that are available to choose from for the holiday selection
12 | typedef enum SLHolidayCountry : NSInteger {
13 | kSLHolidayCountryArgentina,
14 | kSLHolidayCountryAruba,
15 | kSLHolidayCountryAustralia,
16 | kSLHolidayCountryAustria,
17 | kSLHolidayCountryBelarus,
18 | kSLHolidayCountryBelgium,
19 | kSLHolidayCountryBrazil,
20 | kSLHolidayCountryBulgaria,
21 | kSLHolidayCountryCanada,
22 | kSLHolidayCountryChina,
23 | kSLHolidayCountryColombia,
24 | kSLHolidayCountryCroatia,
25 | kSLHolidayCountryCzechia,
26 | kSLHolidayCountryDenmark,
27 | kSLHolidayCountryDominicanRepublic,
28 | kSLHolidayCountryEgypt,
29 | kSLHolidayCountryEstonia,
30 | kSLHolidayCountryFinland,
31 | kSLHolidayCountryFrance,
32 | kSLHolidayCountryGermany,
33 | kSLHolidayCountryHongKong,
34 | kSLHolidayCountryHungary,
35 | kSLHolidayCountryIceland,
36 | kSLHolidayCountryIndia,
37 | kSLHolidayCountryIreland,
38 | kSLHolidayCountryIsrael,
39 | kSLHolidayCountryItaly,
40 | kSLHolidayCountryJapan,
41 | kSLHolidayCountryKenya,
42 | kSLHolidayCountryKorea,
43 | kSLHolidayCountryLithuania,
44 | kSLHolidayCountryLuxembourg,
45 | kSLHolidayCountryMexico,
46 | kSLHolidayCountryMorocco,
47 | kSLHolidayCountryNetherlands,
48 | kSLHolidayCountryNewZealand,
49 | kSLHolidayCountryNicaragua,
50 | kSLHolidayCountryNigeria,
51 | kSLHolidayCountryNorway,
52 | kSLHolidayCountryParaguay,
53 | kSLHolidayCountryPeru,
54 | kSLHolidayCountryPoland,
55 | kSLHolidayCountryPortugal,
56 | kSLHolidayCountryRussia,
57 | kSLHolidayCountrySerbia,
58 | kSLHolidayCountrySingapore,
59 | kSLHolidayCountrySlovakia,
60 | kSLHolidayCountrySlovenia,
61 | kSLHolidayCountrySouthAfrica,
62 | kSLHolidayCountrySpain,
63 | kSLHolidayCountrySweden,
64 | kSLHolidayCountrySwitzerland,
65 | kSLHolidayCountryTaiwan,
66 | kSLHolidayCountryTurkey,
67 | kSLHolidayCountryUkraine,
68 | kSLHolidayCountryUnitedKingdom,
69 | kSLHolidayCountryUnitedStates,
70 | kSLHolidayCountryVietnam,
71 | kSLHolidayCountryNumCountries
72 | } SLHolidayCountry;
73 |
74 | // enum to define the different options that can be returned for the alarm's skip activation
75 | typedef enum SLSkipActivatedStatus : NSInteger {
76 | kSLSkipActivatedStatusUnknown,
77 | kSLSkipActivatedStatusActivated,
78 | kSLSkipActivatedStatusDisabled
79 | } SLSkipActivatedStatus;
80 |
81 | // enum to define the options for whether or not an alarm has the auto-set option enabled
82 | typedef enum SLAutoSetOption : NSInteger {
83 | kSLAutoSetOptionOff,
84 | kSLAutoSetOptionSunrise,
85 | kSLAutoSetOptionSunset
86 | } SLAutoSetOption;
87 |
88 | // enum to define the offset options for the auto-set feature when it is enabled
89 | typedef enum SLAutoSetOffsetOption : NSInteger {
90 | kSLAutoSetOffsetOptionOff,
91 | kSLAutoSetOffsetOptionBefore,
92 | kSLAutoSetOffsetOptionAfter
93 | } SLAutoSetOffsetOption;
94 |
95 | // constants that define the default values
96 | static NSInteger const kSLDefaultSnoozeHour = 0;
97 | static NSInteger const kSLDefaultSnoozeMinute = 9;
98 | static NSInteger const kSLDefaultSnoozeSecond = 0;
99 | static BOOL const kSLDefaultSkipEnabled = NO;
100 | static NSInteger const kSLDefaultSkipHour = 0;
101 | static NSInteger const kSLDefaultSkipMinute = 30;
102 | static NSInteger const kSLDefaultSkipSecond = 0;
103 | static NSInteger const kSLDefaultSkipActivatedStatus = kSLSkipActivatedStatusUnknown;
104 | static NSInteger const kSLDefaultAutoSetOption = kSLAutoSetOptionOff;
105 | static NSInteger const kSLDefaultAutoSetOffsetOption = kSLAutoSetOffsetOptionOff;
106 | static NSInteger const kSLDefaultAutoSetOffsetHour = 1;
107 | static NSInteger const kSLDefaultAutoSetOffsetMinute = 0;
108 |
109 | // Sleeper preferences specific to an alarm
110 | @interface SLAlarmPrefs : NSObject
111 |
112 | // custom initialization that creates a new alarm prefs object with the given alarm Id
113 | // and default preferences
114 | - (instancetype)initWithAlarmId:(NSString *)alarmId;
115 |
116 | // returns the total number of selected holidays to be skipped for the given alarm
117 | - (NSInteger)totalSelectedHolidays;
118 |
119 | // returns a customized string that indicates the total number of selected skip dates and/or holidays
120 | - (NSString *)totalSelectedDatesString;
121 |
122 | // determines whether or not this alarm should be skipped today
123 | - (BOOL)shouldSkipToday;
124 |
125 | // determines whether or not the alarm should be skipped on a given date
126 | - (BOOL)shouldSkipOnDate:(NSDate *)date;
127 |
128 | // returns an explanation of why a given alarm will be skipped
129 | - (NSString *)skipReasonExplanation;
130 |
131 | // returns an explanation regarding the use of the auto-set option
132 | - (NSString *)autoSetExplanation;
133 |
134 | // alarm Id associated with this preference object
135 | @property (nonatomic, strong) NSString *alarmId;
136 |
137 | // the snooze hour
138 | @property (nonatomic) NSInteger snoozeTimeHour;
139 |
140 | // the snooze minute
141 | @property (nonatomic) NSInteger snoozeTimeMinute;
142 |
143 | // the snooze second
144 | @property (nonatomic) NSInteger snoozeTimeSecond;
145 |
146 | // whether or not skip is enabled
147 | @property (nonatomic) BOOL skipEnabled;
148 |
149 | // the skip hour
150 | @property (nonatomic) NSInteger skipTimeHour;
151 |
152 | // the skip minute
153 | @property (nonatomic) NSInteger skipTimeMinute;
154 |
155 | // the skip second
156 | @property (nonatomic) NSInteger skipTimeSecond;
157 |
158 | // the skip activation status
159 | @property (nonatomic) SLSkipActivatedStatus skipActivationStatus;
160 |
161 | // the auto-set option
162 | @property (nonatomic) SLAutoSetOption autoSetOption;
163 |
164 | // the auto-set offset option
165 | @property (nonatomic) SLAutoSetOffsetOption autoSetOffsetOption;
166 |
167 | // the auto-set offset hour
168 | @property (nonatomic) NSInteger autoSetOffsetHour;
169 |
170 | // the auto-set offset minute
171 | @property (nonatomic) NSInteger autoSetOffsetMinute;
172 |
173 | // an array of NSDate objects that represent the custom skip dates for this alarm
174 | @property (nonatomic, strong) NSArray *customSkipDates;
175 |
176 | // a dictionary containing additional dictionaries that correspond to the selected holidays per country
177 | @property (nonatomic, strong) NSDictionary *holidaySkipDates;
178 |
179 | @end
180 |
--------------------------------------------------------------------------------
/common/SLAutoSetManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLAutoSetManager.h
3 | // A singleton object that will be used to manage the auto-set feature.
4 | //
5 | // Created by Joshua Seltzer on 6/27/20.
6 | // Copyright (c) 2020 Joshua Seltzer. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "SLAlarmPrefs.h"
11 |
12 | // the notification key that will be fired when the auto-set options are updated for a specific alarm
13 | static NSString *const kSLAutoSetOptionsUpdatedNotification = @"SLAutoSetOptionsUpdated";
14 |
15 | // the location object that will be associated with a forecast model
16 | @interface WFLocation : NSObject
17 |
18 | // the time zone that is associated with the location
19 | @property (nonatomic, copy) NSTimeZone *timeZone;
20 |
21 | @end
22 |
23 | // an object which contains information about the current forecast
24 | @interface WAForecastModel : NSObject
25 |
26 | // the sunrise and sunset times for this forecast
27 | @property (nonatomic, retain) NSDate *sunrise;
28 | @property (nonatomic, retain) NSDate *sunset;
29 |
30 | // the location object associated with the forecast model
31 | @property (nonatomic, retain) WFLocation *location;
32 |
33 | @end
34 |
35 | // preferences object that will be used to request the model
36 | @interface WeatherPreferences : NSObject
37 |
38 | // the shared preferences that will be utilized to get updates from the today model
39 | + (id)sharedPreferences;
40 |
41 | @end
42 |
43 | // the today model which will be used to provide us with the sunrise/sunset times
44 | @interface WATodayModel : NSObject
45 |
46 | // returns a WATodayAutoupdatingLocationModel instance that can be used to monitor changes to the today model
47 | + (id)autoupdatingLocationModelWithPreferences:(WeatherPreferences *)weatherPreferences
48 | effectiveBundleIdentifier:(NSString *)bundleIdentifier;
49 |
50 | // the forecast model that is associated with this today model
51 | @property (nonatomic, retain) WAForecastModel *forecastModel;
52 |
53 | @end
54 |
55 | // manager that will be used to automatically update alarms based on the user preferences
56 | @interface SLAutoSetManager : NSObject
57 |
58 | // return a singleton instance of this manager
59 | + (instancetype)sharedInstance;
60 |
61 | // routine to update to a single alarm object that has updated auto-set settings
62 | - (void)updateAutoSetAlarm:(NSDictionary *)alarmDict;
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/common/SLCommonHeaders.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLUserInterfaceHeaders.h
3 | // Contains all interfaces that are shared among the various components.
4 | //
5 | // Created by Joshua Seltzer on 2/15/20.
6 | //
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import
13 | #import
14 | #import
15 |
16 | // iOS 8 / iOS 9: the notification that gets fired when the user decides to snooze an alarm
17 | @interface UIConcreteLocalNotification : UILocalNotification
18 |
19 | // returns a date for a given notification that will happen after a date in a given time zone
20 | - (NSDate *)nextFireDateAfterDate:(NSDate *)date localTimeZone:(NSTimeZone *)timeZone;
21 |
22 | @end
23 |
24 | // legacy notification trigger object which is a subclass of a standard notification trigger
25 | @interface UNLegacyNotificationTrigger : UNNotificationTrigger
26 |
27 | // returns a date for a given notification that will happen after a date in a given time zone
28 | - (NSDate *)_nextTriggerDateAfterDate:(NSDate *)date withRequestedDate:(NSDate *)requestedDate defaultTimeZone:(NSTimeZone *)timeZone;
29 |
30 | @end
31 |
32 | // additional details/content associated with a notification request
33 | @interface UNNotificationContent (Private)
34 |
35 | // iOS 10: determines whether or not the notification is from a snooze notification
36 | - (BOOL)isFromSnooze;
37 |
38 | @end
39 |
40 | // iOS 10 / iOS 11: the notification record object that gets fired when the user snoozes the alarm
41 | @interface UNSNotificationRecord : NSObject
42 |
43 | // user information attached to this notification record
44 | @property (nonatomic, copy) NSDictionary *userInfo;
45 |
46 | // the trigger date for the notification
47 | @property (nonatomic, copy) NSDate *triggerDate;
48 |
49 | // sets the trigger date for this notification
50 | - (void)setTriggerDate:(NSDate *)date;
51 |
52 | // returns whether or not this notification record is from a snooze action
53 | - (BOOL)isFromSnooze;
54 |
55 | @end
56 |
57 | // iOS 8 - iOS 11: the alarm object that contains all of the information about the alarm
58 | @interface Alarm : NSObject
59 |
60 | // iOS 8: the alarm Id corresponding to the alarm object
61 | @property (readonly) NSString *alarmId;
62 |
63 | // iOS 9 / iOS 10 / iOS 11: the alarm Id corresponding to the alarm object
64 | @property (nonatomic, retain) NSString *alarmID;
65 |
66 | // the display title of the alarm
67 | @property (readonly, nonatomic) NSString *uiTitle;
68 |
69 | // tells us if the given notification object was generated from a snooze notification (iOS 8 / iOS 9)
70 | + (BOOL)isSnoozeNotification:(UIConcreteLocalNotification *)notification;
71 |
72 | // returns the next date that this alarm will fire
73 | - (NSDate *)nextFireDate;
74 |
75 | // simulates when an alarm gets fired
76 | - (void)handleAlarmFired:(UIConcreteLocalNotification *)notification;
77 |
78 | // iOS 10 / iOS 11: determines whether or not the alarm is the sleep/bedtime alarm
79 | - (BOOL)isSleepAlarm;
80 |
81 | // updates the hour property of the alarm
82 | - (void)setHour:(NSUInteger)hour;
83 |
84 | // updates the minute property of the alarm
85 | - (void)setMinute:(NSUInteger)minute;
86 |
87 | // whether or not the alarm is active
88 | - (BOOL)isActive;
89 |
90 | // populates the editing proxy for the alarm
91 | - (void)prepareEditingProxy;
92 |
93 | // returns the editing proxy for this alarm
94 | - (Alarm *)editingProxy;
95 |
96 | // applies any changes to the editing proxy to the alarm itself
97 | - (void)applyChangesFromEditingProxy;
98 |
99 | @end
100 |
101 | // iOS 8 - iOS 11: manager that governs all alarms on the system
102 | @interface AlarmManager : NSObject
103 |
104 | // iOS 10 / iOS 11: the special sleep alarm (i.e. Bedtime alarm)
105 | @property (nonatomic, readonly) Alarm *sleepAlarm;
106 |
107 | // the shared alarm manager
108 | + (id)sharedManager;
109 |
110 | // loads the alarms on the system in the manager object
111 | - (void)loadAlarms;
112 |
113 | // simulates when an alarm gets fired
114 | - (void)handleNotificationFired:(UIConcreteLocalNotification *)notification;
115 |
116 | // returns an alarm object from a given alarm Id
117 | - (Alarm *)alarmWithId:(NSString *)alarmId;
118 |
119 | // updates a given alarm
120 | - (void)updateAlarm:(Alarm *)alarm active:(BOOL)active;
121 |
122 | @end
123 |
124 | // iOS 12+: the alarm object
125 | @interface MTAlarm : NSObject
126 |
127 | // the title of the alarm
128 | @property (readonly, nonatomic) NSString *displayTitle;
129 |
130 | // signifies whether or not this alarm is snozoed
131 | @property (readonly, nonatomic, getter=isSnoozed) BOOL snoozed;
132 |
133 | // updates the hour property of the alarm
134 | - (void)setHour:(NSInteger)hour;
135 |
136 | // updates the minute property of the alarm
137 | - (void)setMinute:(NSInteger)minute;
138 |
139 | // returns a string representation of the alarm Id
140 | - (NSString *)alarmIDString;
141 |
142 | // returns the next fire date for the alarm given a start date
143 | - (NSDate *)nextFireDateAfterDate:(NSDate *)date includeBedtimeNotification:(BOOL)includeBedtimeNotification;
144 |
145 | // indicates whether or not this is the special Bedtime / sleep alarm
146 | - (BOOL)isSleepAlarm;
147 |
148 | @end
149 |
150 | // custom interface for added properties
151 | @interface MTAlarm (Sleeper)
152 |
153 | // flag which indicates whether or not the alarm was updated by this tweak or not
154 | @property (nonatomic, assign) BOOL SLWasUpdatedBySleeper;
155 |
156 | @end
157 |
158 | // iOS 12+: an extension to the MTAlarm interface indicating an editable alarm
159 | @interface MTMutableAlarm : MTAlarm
160 | @end
161 |
162 | // iOS 12+: the data source corresponding to a particular alarm
163 | @interface MTAlarmDataSource : NSObject
164 |
165 | // the sleep alarm that corresponds to the alarm data source object
166 | @property (retain, nonatomic) MTAlarm *sleepAlarm;
167 |
168 | @end
169 |
170 | // manager that governs all alarms on the system (iOS 12 - iOS 14)
171 | @interface MTAlarmManager : NSObject
172 |
173 | // invoked when an alarm is saved
174 | - (id)updateAlarm:(MTMutableAlarm *)mutableAlarm;
175 |
176 | // returns an array of MTAlarm objects for the given date and
177 | - (NSArray *)nextAlarmsForDateSync:(NSDate *)date maxCount:(int)maxCount includeSleepAlarm:(BOOL)includeSleepAlarm includeBedtimeNotification:(BOOL)includeBedtimeNotification;
178 |
179 | // returns an alarm object given the corresponding alarm Id string
180 | - (MTAlarm *)alarmWithIDString:(NSString *)alarmId;
181 |
182 | @end
183 |
184 | // iOS 8 - iOS 11: data provider which lets us know which alarms have notifications scheduled
185 | @interface SBClockDataProvider : NSObject
186 |
187 | // the shared instance of the clock data provider
188 | + (id)sharedInstance;
189 |
190 | // iOS 8: return all scheduled notifications that are held by the clock data provider
191 | - (NSArray *)_scheduledNotifications;
192 |
193 | // returns an alarm Id for a given notification
194 | - (NSString *)_alarmIDFromNotification:(UIConcreteLocalNotification *)notification;
195 |
196 | // iOS 10 / iOS 11: returns an alarm Id for a given notification request
197 | - (NSString *)_alarmIDFromNotificationRequest:(UNNotificationRequest *)notificationRequest;
198 |
199 | // lets us know whether or not a given notification is an alarm notification
200 | // iOS 8 / iOS 9: argument is a UIConcreteLocalNotification object
201 | // iOS 10 / iOS 11: argument is a UNNotification object
202 | - (BOOL)_isAlarmNotification:(id)notification;
203 |
204 | // iOS 10 / iOS 11: whether or not a given notification request is an alarm notification
205 | - (BOOL)_isAlarmNotificationRequest:(UNNotificationRequest *)notificationRequest;
206 |
207 | // iOS 8 / iOS 9: invoked when an alarm alert (i.e. bulletin) is about to be displayed
208 | - (void)_publishBulletinForLocalNotification:(UIConcreteLocalNotification *)notification;
209 |
210 | // iOS 10 / iOS 11: invoked when an alarm alert (i.e. bulletin) is about to be displayed
211 | - (void)_publishBulletinForNotification:(id)notification;
212 |
213 | @end
214 |
215 | // iOS 9 / iOS 10 / iOS 11: manages the notifications for clocks and alarms
216 | @interface SBClockNotificationManager : NSObject
217 |
218 | // the shared instance of the notification manager
219 | + (id)sharedInstance;
220 |
221 | // iOS 9: returns the array of scheduled local notifications
222 | - (NSArray *)scheduledLocalNotifications;
223 |
224 | // iOS 10 / iOS 11: returns pending notification request objects in the completion handler
225 | - (void)getPendingNotificationRequestsWithCompletionHandler:(void (^)(NSArray *requests))completionHandler;
226 |
227 | @end
--------------------------------------------------------------------------------
/common/SLCompatibilityHelper.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLCompatibilityHelper.h
3 | // Functions that are used to maintain system compatibility between different iOS versions.
4 | //
5 | // Created by Joshua Seltzer on 10/14/15.
6 | //
7 | //
8 |
9 | #import "SLCommonHeaders.h"
10 |
11 | // define the core foundation version numbers if they have not already been defined
12 | // http://iphonedevwiki.net/index.php/CoreFoundation.framework
13 | #ifndef kCFCoreFoundationVersionNumber_iOS_8_0
14 | #define kCFCoreFoundationVersionNumber_iOS_8_0 1100.00
15 | #endif
16 |
17 | #ifndef kCFCoreFoundationVersionNumber_iOS_9_0
18 | #define kCFCoreFoundationVersionNumber_iOS_9_0 1200.00
19 | #endif
20 |
21 | #ifndef kCFCoreFoundationVersionNumber_iOS_10_0
22 | #define kCFCoreFoundationVersionNumber_iOS_10_0 1300.00
23 | #endif
24 |
25 | #ifndef kCFCoreFoundationVersionNumber_iOS_11_0
26 | #define kCFCoreFoundationVersionNumber_iOS_11_0 1400.00
27 | #endif
28 |
29 | #ifndef kCFCoreFoundationVersionNumber_iOS_12_0
30 | #define kCFCoreFoundationVersionNumber_iOS_12_0 1500.00
31 | #endif
32 |
33 | #ifndef kCFCoreFoundationVersionNumber_iOS_13_0
34 | #define kCFCoreFoundationVersionNumber_iOS_13_0 1600.00
35 | #endif
36 |
37 | #ifndef kCFCoreFoundationVersionNumber_iOS_14_0
38 | #define kCFCoreFoundationVersionNumber_iOS_14_0 1700.00
39 | #endif
40 |
41 | // create definitions for the different versions of iOS that are supported by Sleeper
42 | #define kSLSystemVersioniOS14 kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_14_0
43 | #define kSLSystemVersioniOS13 (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_13_0 && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_14_0)
44 | #define kSLSystemVersioniOS12 (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_12_0 && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_13_0)
45 | #define kSLSystemVersioniOS11 (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_11_0 && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_12_0)
46 | #define kSLSystemVersioniOS10 (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_10_0 && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_11_0)
47 | #define kSLSystemVersioniOS9 (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_9_0 && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_10_0)
48 | #define kSLSystemVersioniOS8 (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0 && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_9_0)
49 |
50 | // interface for version compatibility functions throughout the application
51 | @interface SLCompatibilityHelper : NSObject
52 |
53 | // iOS 8 / iOS 9: modifies a snooze UIConcreteLocalNotification object with the selected snooze time (if applicable)
54 | + (void)modifySnoozeNotificationForLocalNotification:(UIConcreteLocalNotification *)localNotification;
55 |
56 | // iOS 10 / iOS 11: modifies a snooze UNSNotificationRecord object with the selected snooze time (if applicable)
57 | + (void)modifySnoozeNotificationForNotificationRecord:(UNSNotificationRecord *)notificationRecord;
58 |
59 | // Returns a modified NSDate object with an appropriately modified snooze time for a given alarm Id and original date
60 | // Returns nil if no modified snooze date is available
61 | + (NSDate *)modifiedSnoozeDateForAlarmId:(NSString *)alarmId withOriginalDate:(NSDate *)originalDate;
62 |
63 | // iOS 8 / iOS 9: Returns the next skippable alarm local notification. If there is no skippable notification found, return nil.
64 | + (UIConcreteLocalNotification *)nextSkippableAlarmLocalNotification;
65 |
66 | // iOS 10 / iOS 11: Returns the next skippable alarm notification request given an array of notification requests.
67 | // If there is no skippable notification found, return nil.
68 | + (UNNotificationRequest *)nextSkippableAlarmNotificationRequestForNotificationRequests:(NSArray *)notificationRequests;
69 |
70 | // returns whether or not an alarm is skippable based on the alarm Id
71 | + (BOOL)isAlarmSkippableForAlarmId:(NSString *)alarmId withNextFireDate:(NSDate *)nextFireDate;
72 |
73 | // returns a valid alarm Id for a given alarm
74 | + (NSString *)alarmIdForAlarm:(Alarm *)alarm;
75 |
76 | // returns the appropriate title string for a given Alarm object
77 | + (NSString *)alarmTitleForAlarm:(Alarm *)alarm;
78 |
79 | // returns the appropriate title string for a given MTAlarm object
80 | + (NSString *)alarmTitleForMTAlarm:(MTAlarm *)alarm;
81 |
82 | // returns the picker view's background color, which will depend on the iOS version
83 | + (UIColor *)pickerViewBackgroundColor;
84 |
85 | // returns the color of the standard labels used throughout the tweak
86 | + (UIColor *)defaultLabelColor;
87 |
88 | // returns the color of the destructive labels used throughout the tweak
89 | + (UIColor *)destructiveLabelColor;
90 |
91 | // iOS 13: returns the background color used for cells used in the various views
92 | + (UIColor *)tableViewCellBackgroundColor;
93 |
94 | // iOS 10, iOS 11, iOS 12, iOS 13: returns the cell selection background color for cells
95 | + (UIColor *)tableViewCellSelectedBackgroundColor;
96 |
97 | // modifies an alert controller's subviews appropriately if necessary for the current version of iOS
98 | + (void)updateSubviewsForAlertController:(UIAlertController *)alertController;
99 |
100 | // uses the appearance API to modify the look and feel of a UIAlertController's various views for the current version of iOS
101 | + (void)updateDefaultUIAlertControllerAppearance;
102 |
103 | // returns the checkmark image used to indicate selection throughout the UI
104 | + (UIImage *)checkmarkImage;
105 |
106 | // returns the "open in" image
107 | + (UIImage *)openInImage;
108 |
109 | // returns whether or not the device is even capable of using the auto-set feature (requires iOS 10 and iPhone device)
110 | + (BOOL)canHaveAutoSet;
111 |
112 | // returns whether or not the device is in a state that can use the auto-set feature
113 | + (BOOL)canEnableAutoSet;
114 |
115 | // navigates the user to the Weather application
116 | + (void)openWeatherApplication;
117 |
118 | // Updates the given alarms (represented as SLAlarmPref dictionaries) with the base hour and base minute.
119 | // The implementation of updating the alarms will differ depending on which iOS is currently running.
120 | + (void)updateAlarms:(NSArray *)alarms withBaseHour:(NSInteger)baseHour withBaseMinute:(NSInteger)baseMinute;
121 |
122 | // returns an NSBundle object corresponding to the SleepHealthUI Private Framework
123 | + (NSBundle *)sleepHealthUIBundle;
124 |
125 | // returns the internally used alarm ID for the new "Wake Up" alarm (iOS 14)
126 | + (NSString *)wakeUpAlarmId;
127 |
128 | @end
--------------------------------------------------------------------------------
/common/SLPrefsManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLPrefsManager.h
3 | // The preferences manager for the tweak.
4 | //
5 | // Created by Joshua Seltzer on 12/8/14.
6 | // Copyright (c) 2014 Joshua Seltzer. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "SLAlarmPrefs.h"
11 |
12 | // the bundle path which includes some custom preference files needed for the tweak
13 | #define kSLSleeperBundle [NSBundle bundleWithPath:@"/Library/Application Support/Sleeper.bundle"]
14 |
15 | // define the bundle identifier for the tweak
16 | static NSString *const kSLBundleIdentifier = @"com.joshuaseltzer.sleeper";
17 |
18 | // constant keys for the values we are going to add to the preferences file
19 | static NSString *const kSLAlarmsKey = @"Alarms";
20 | static NSString *const kSLAlarmIdKey = @"alarmId";
21 | static NSString *const kSLSnoozeHourKey = @"snoozeTimeHour";
22 | static NSString *const kSLSnoozeMinuteKey = @"snoozeTimeMinute";
23 | static NSString *const kSLSnoozeSecondKey = @"snoozeTimeSecond";
24 | static NSString *const kSLSkipEnabledKey = @"skipEnabled";
25 | static NSString *const kSLSkipHourKey = @"skipTimeHour";
26 | static NSString *const kSLSkipMinuteKey = @"skipTimeMinute";
27 | static NSString *const kSLSkipSecondKey = @"skipTimeSecond";
28 | static NSString *const kSLSkipActivatedStatusKey = @"skipActivatedStatus";
29 | static NSString *const kSLSkipDatesKey = @"skipDates";
30 | static NSString *const kSLHolidaySkipDatesKey = @"holidaySkipDates";
31 | static NSString *const kSLCustomSkipDatesKey = @"customSkipDates";
32 | static NSString *const kSLCustomSkipDateStringsKey = @"customSkipDateStrings";
33 | static NSString *const kSLHolidayHolidaysKey = @"holidays";
34 | static NSString *const kSLHolidayNameKey = @"name";
35 | static NSString *const kSLHolidayDatesKey = @"dates";
36 | static NSString *const kSLAutoSetOptionKey = @"autoSetOption";
37 | static NSString *const kSLAutoSetOffsetOptionKey = @"autoSetOffsetOption";
38 | static NSString *const kSLAutoSetOffsetHourKey = @"autoSetOffsetHour";
39 | static NSString *const kSLAutoSetOffsetMinuteKey = @"autoSetOffsetMinute";
40 |
41 | // define the key that will be used in the notification sent to observers when auto-set alarms are updated
42 | static NSString *const kSLUpdatedAutoSetAlarmNotificationKey = @"updatedAutoSetAlarm";
43 |
44 | @class SLAlarmPrefs;
45 |
46 | // manager that manages the retrieval, saving, and deleting of custom snooze times
47 | @interface SLPrefsManager : NSObject
48 |
49 | // returns the date formatter for converting to and from saving to the plist
50 | + (NSDateFormatter *)plistDateFormatter;
51 |
52 | // Return an SLAlarmPrefs object with alarm information for a given alarm Id. Return nil if no alarm is found.
53 | + (SLAlarmPrefs *)alarmPrefsForAlarmId:(NSString *)alarmId;
54 |
55 | // returns whether or not the preferences file contains preferences for an alarm with the given alarm Id
56 | + (BOOL)prefsContainAlarmWithAlarmId:(NSString *)alarmId;
57 |
58 | // save the specific alarm preferences object
59 | + (void)saveAlarmPrefs:(SLAlarmPrefs *)alarmPrefs;
60 |
61 | // save the skip activation status for a given alarm
62 | + (void)setSkipActivatedStatusForAlarmId:(NSString *)alarmId
63 | skipActivatedStatus:(SLSkipActivatedStatus)skipActivatedStatus;
64 |
65 | // delete an alarm from our settings
66 | + (void)deleteAlarmForAlarmId:(NSString *)alarmId;
67 |
68 | // Provides the caller with a dictionary containing all of the auto-set alarms using the auto-set option as the key for the dictionary.
69 | // The value for each key will be an array containing dictionaries with the alarm information.
70 | // Returns nil when no auto-set alarms exist.
71 | + (NSDictionary *)allAutoSetAlarms;
72 |
73 | // Returns a dictionary that corresponds to the default holiday source for the given holiday resource name.
74 | // This function will also remove any passed dates.
75 | + (NSDictionary *)holidayResourceForResourceName:(NSString *)resourceName;
76 |
77 | // Returns the first available skip date for the given holiday name and country. This function will not take into consideration any passed dates.
78 | + (NSDate *)firstSkipDateForHolidayName:(NSString *)holidayName inHolidayCountry:(SLHolidayCountry)holidayCountry;
79 |
80 | // returns a corresponding country code for any given country
81 | + (NSString *)countryCodeForHolidayCountry:(SLHolidayCountry)country;
82 |
83 | // returns a string that corresponds to the resource name for a given holiday country
84 | + (NSString *)resourceNameForHolidayCountry:(SLHolidayCountry)country;
85 |
86 | // returns a string that corresponds to the resource name for a given country code
87 | + (NSString *)resourceNameForCountryCode:(NSString *)countryCode;
88 |
89 | // returns the localized, friendly name to be displayed for the given country
90 | + (NSString *)friendlyNameForHolidayCountry:(SLHolidayCountry)country;
91 |
92 | // returns the localized, friendly name to be displayed for an auto-set option
93 | + (NSString *)friendlyNameForAutoSetOption:(SLAutoSetOption)autoSetOption;
94 |
95 | // returns the localized, friendly name to be displayed for an auto-set offset option
96 | + (NSString *)friendlyNameForAutoSetOffsetOption:(SLAutoSetOffsetOption)autoSetOffsetOption;
97 |
98 | // Returns a string that represents a date that is going to be skipped. If showRelativeString is enabled,
99 | // a relative string is shown instead (i.e. Today, Tomorrow)
100 | + (NSString *)skipDateStringForDate:(NSDate *)date showRelativeString:(BOOL)showRelativeString;
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/common/SLSkipAlarmAlertItem.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLSkipAlarmAlertItem.h
3 | // Custom system alert item to ask the user if he or she would like to skip a given alarm.
4 | //
5 | // Created by Joshua Seltzer on 8/9/15.
6 | //
7 | //
8 |
9 | #import "SLCommonHeaders.h"
10 |
11 | // a system alert item
12 | @interface SBAlertItem : NSObject
13 |
14 | // the alert controlelr object that corresponds to this alert item
15 | - (UIAlertController *)alertController;
16 |
17 | // allows us to set up the alert view or alert controller
18 | - (void)configure:(BOOL)configure requirePasscodeForActions:(BOOL)requirePasscode;
19 |
20 | // dismisses the alert item
21 | - (void)dismiss;
22 |
23 | @end
24 |
25 | // the controller responsible for activating and displaying system alert items
26 | @interface SBAlertItemsController : UIViewController
27 |
28 | // the shared instance of this controller
29 | + (id)sharedInstance;
30 |
31 | // activates/displays an alert item to the user
32 | - (void)activateAlertItem:(SBAlertItem *)alertItem animated:(BOOL)animated;
33 |
34 | // Returns whether or not the alert items controller contains an alert of a given class. We will utilize this method
35 | // to ensure that only a single SLSkipAlarmAlertItem is being shown at once.
36 | - (BOOL)hasAlertOfClass:(Class)alertClass;
37 |
38 | @end
39 |
40 | // system alert for skipping alarms
41 | @interface SLSkipAlarmAlertItem : SBAlertItem
42 |
43 | // create a new alert item with a given title, alarmId, and next fire date
44 | - (id)initWithTitle:(NSString *)title alarmId:(NSString *)alarmId nextFireDate:(NSDate *)nextFireDate;
45 |
46 | @end
--------------------------------------------------------------------------------
/common/SLSkipAlarmAlertItem.xm:
--------------------------------------------------------------------------------
1 | //
2 | // SLSkipAlarmAlertItem.xm
3 | // Custom system alert item to ask the user if he or she would like to skip a given alarm.
4 | //
5 | // Created by Joshua Seltzer on 8/9/15.
6 | //
7 | //
8 |
9 | #import "SLSkipAlarmAlertItem.h"
10 | #import "SLPrefsManager.h"
11 | #import "SLLocalizedStrings.h"
12 | #import "SLCompatibilityHelper.h"
13 |
14 | // private interface definition to define some properties
15 | @interface SLSkipAlarmAlertItem (Sleeper)
16 |
17 | @property (nonatomic, retain) NSString *SLTitle;
18 | @property (nonatomic, retain) NSString *SLAlarmId;
19 | @property (nonatomic, retain) NSDate *SLAlertFireDate;
20 |
21 | @end
22 |
23 | // keep a single static instance of the date formatter that will be used to display the time to the user
24 | static NSDateFormatter *sSLSAlertDateFormatter;
25 |
26 | %subclass SLSkipAlarmAlertItem : SBAlertItem
27 |
28 | // the title associated with this alert
29 | %property (nonatomic, retain) NSString *SLTitle;
30 |
31 | // the alarmId associated with the alarm being displayed in this alert
32 | %property (nonatomic, retain) NSString *SLAlarmId;
33 |
34 | // the fire date for the alarm in this alert
35 | %property (nonatomic, retain) NSDate *SLAlertFireDate;
36 |
37 | // create a new alert item with a given title, alarmId, and next fire date
38 | %new
39 | - (id)initWithTitle:(NSString *)title alarmId:(NSString *)alarmId nextFireDate:(NSDate *)nextFireDate
40 | {
41 | self = [self init];
42 | if (self) {
43 | self.SLTitle = title;
44 | self.SLAlarmId = alarmId;
45 | self.SLAlertFireDate = nextFireDate;
46 |
47 | // create the date formatter object once since date formatters are expensive
48 | static dispatch_once_t once;
49 | dispatch_once(&once, ^{
50 | sSLSAlertDateFormatter = [[NSDateFormatter alloc] init];
51 | sSLSAlertDateFormatter.dateFormat = @"h:mm a";
52 | });
53 | }
54 | return self;
55 | }
56 |
57 | - (void)dealloc
58 | {
59 | // clear out some properties associated with this alert
60 | self.SLTitle = nil;
61 | self.SLAlarmId = nil;
62 | self.SLAlertFireDate = nil;
63 |
64 | %orig;
65 | }
66 |
67 | // configure the alert with the alarm properties
68 | - (void)configure:(BOOL)configure requirePasscodeForActions:(BOOL)requirePasscode
69 | {
70 | %orig;
71 |
72 | // customize the alert controller
73 | self.alertController.title = kSLSkipAlarmString;
74 | self.alertController.message = kSLSkipQuestionString(self.SLTitle, [sSLSAlertDateFormatter stringFromDate:self.SLAlertFireDate]);
75 |
76 | // add yes, no, and cancel actions to the alert controller
77 | UIAlertAction *yesAction = [UIAlertAction actionWithTitle:kSLYesString
78 | style:UIAlertActionStyleDestructive
79 | handler:^(UIAlertAction * _Nonnull action) {
80 | // save the alarm's skip activation state to our preferences
81 | [SLPrefsManager setSkipActivatedStatusForAlarmId:self.SLAlarmId
82 | skipActivatedStatus:kSLSkipActivatedStatusActivated];
83 | [self dismiss];
84 | }];
85 | UIAlertAction *noAction = [UIAlertAction actionWithTitle:kSLNoString
86 | style:UIAlertActionStyleDefault
87 | handler:^(UIAlertAction * _Nonnull action) {
88 | // save the alarm's skip activation state to our preferences
89 | [SLPrefsManager setSkipActivatedStatusForAlarmId:self.SLAlarmId
90 | skipActivatedStatus:kSLSkipActivatedStatusDisabled];
91 | [self dismiss];
92 | }];
93 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:kSLCancelString
94 | style:UIAlertActionStyleCancel
95 | handler:^(UIAlertAction * _Nonnull action) {
96 | [self dismiss];
97 | }];
98 |
99 | // add the actions to the alert controller
100 | [self.alertController addAction:yesAction];
101 | [self.alertController addAction:noAction];
102 | [self.alertController addAction:cancelAction];
103 |
104 | // if the alert still exists, be sure to dismiss the alert just before the alarm will fire
105 | __weak typeof(self) weakSelf = self;
106 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(([self.SLAlertFireDate timeIntervalSinceDate:[NSDate date]] - 1.0f) * NSEC_PER_SEC));
107 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
108 | // if the alert still exists, then automatically dismiss the alert
109 | if (weakSelf) {
110 | [weakSelf dismiss];
111 | }
112 | });
113 | }
114 |
115 | // do no allow the alert to be shown during an emergency call
116 | - (BOOL)shouldShowInEmergencyCall
117 | {
118 | return NO;
119 | }
120 |
121 | // do not allow the alert to be shown on the lock screen
122 | - (BOOL)shouldShowInLockScreen
123 | {
124 | return NO;
125 | }
126 |
127 | // do not allow the alert to be shown in Apple CarPlay
128 | - (BOOL)allowInCar
129 | {
130 | return NO;
131 | }
132 |
133 | // do not allow the alert to be shown during setup
134 | - (BOOL)allowInSetup
135 | {
136 | return NO;
137 | }
138 |
139 | // always return YES so that the alert is automatically dismissed if the user locks the phone
140 | - (BOOL)dismissOnLock
141 | {
142 | return YES;
143 | }
144 |
145 | %end
146 |
--------------------------------------------------------------------------------
/common/SLSpringBoard.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLSpringBoard.x
3 | // Hooks into the SpringBoard application to run our singleton process that will potentially monitor changes to timers.
4 | //
5 | // Created by Joshua Seltzer on 7/2/2020.
6 | //
7 | //
8 |
9 | #import
10 | #import
11 | #import "../common/SLCompatibilityHelper.h"
12 | #import "../common/SLAutoSetManager.h"
13 |
14 | %hook SpringBoard
15 |
16 | // called whenever an auto-set alarm needs to be updated
17 | %new
18 | - (void)SLAutoSetOptionsUpdated:(NSNotification *)notification
19 | {
20 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
21 | // notify the auto-set manager that an alarm has updated auto-set options
22 | [[SLAutoSetManager sharedInstance] updateAutoSetAlarm:[notification userInfo]];
23 | });
24 | }
25 |
26 | - (void)applicationDidFinishLaunching:(UIApplication *)application
27 | {
28 | %orig;
29 |
30 | // create the auto-set manager instance to potentially monitor changes to alarms
31 | [SLAutoSetManager sharedInstance];
32 |
33 | // observe changes from the auto-set manager to update alarms with updated auto-set options
34 | [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(SLAutoSetOptionsUpdated:) name:kSLAutoSetOptionsUpdatedNotification object:nil];
35 | }
36 |
37 | %end
38 |
39 | %ctor {
40 | // only initialize this file for particular versions
41 | if ([SLCompatibilityHelper canHaveAutoSet]) {
42 | %init();
43 | }
44 | }
--------------------------------------------------------------------------------
/control:
--------------------------------------------------------------------------------
1 | Package: org.packix.sleeper
2 | Name: Sleeper (iOS 8-14)
3 | Depends: mobilesubstrate, firmware (>=8.0), firmware (<<15.0)
4 | Version: 7.0.5
5 | Architecture: iphoneos-arm
6 | Conflicts: org.thebigboss.sleeper
7 | Replaces: org.thebigboss.sleeper
8 | Description: Set custom snooze times and skip alarms with the Clock app using Sleeper!
9 | Maintainer: Joshua Seltzer
10 | Author: Joshua Seltzer
11 | Section: Tweaks
12 | Icon: file:///Library/Application%20Support/Sleeper.bundle/icon.png
13 |
--------------------------------------------------------------------------------
/control_BigBoss:
--------------------------------------------------------------------------------
1 | Package: org.thebigboss.sleeper
2 | Name: Sleeper (Legacy) (iOS 8-14)
3 | Depends: mobilesubstrate, firmware (>=8.0), firmware (<<15.0)
4 | Version: 7.0.5
5 | Architecture: iphoneos-arm
6 | Conflicts: org.packix.sleeper
7 | Description: Set custom snooze times and skip alarms with the Clock app using Sleeper!
8 | Maintainer: Joshua Seltzer
9 | Author: Joshua Seltzer
10 | Section: Tweaks
11 | Icon: file:///Library/Application%20Support/Sleeper.bundle/icon.png
12 |
--------------------------------------------------------------------------------
/control_Havoc:
--------------------------------------------------------------------------------
1 | Package: org.packix.sleeper
2 | Name: Sleeper (iOS 8-14)
3 | Depends: mobilesubstrate, firmware (>=8.0), firmware (<<15.0)
4 | Version: 7.0.5
5 | Architecture: iphoneos-arm
6 | Conflicts: org.thebigboss.sleeper
7 | Replaces: org.thebigboss.sleeper
8 | Description: Set custom snooze times and skip alarms with the Clock app using Sleeper!
9 | Maintainer: Joshua Seltzer
10 | Author: Joshua Seltzer
11 | Section: Tweaks
12 | Icon: file:///Library/Application%20Support/Sleeper.bundle/icon.png
13 |
--------------------------------------------------------------------------------
/core/SLMTAlarm.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLMTAlarm.x
3 | // The alarm object used for iOS 12+.
4 | //
5 | // Created by Joshua Seltzer on 7/30/2020.
6 | //
7 | //
8 |
9 | #import "../common/SLCompatibilityHelper.h"
10 | #import "../common/SLPrefsManager.h"
11 |
12 | %hook MTAlarm
13 |
14 | // flag which indicates whether or not the alarm was updated by this tweak or not
15 | %property (nonatomic, assign) BOOL SLWasUpdatedBySleeper;
16 |
17 | %end
18 |
19 | %ctor {
20 | // only initialize this file for particular versions
21 | if (kSLSystemVersioniOS14 || kSLSystemVersioniOS13 || kSLSystemVersioniOS12) {
22 | %init();
23 | }
24 | }
--------------------------------------------------------------------------------
/core/SLMTAlarmManager.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLMTAlarmManager.x
3 | // Modify Apple's internal class for managing alarms (iOS 12 and iOS 13).
4 | //
5 | // Created by Joshua Seltzer on 3/16/2019.
6 | //
7 | //
8 |
9 | #import "../common/SLCompatibilityHelper.h"
10 | #import "../common/SLPrefsManager.h"
11 |
12 | // alarm manager used in modern versions of iOS
13 | %hook MTAlarmManager
14 |
15 | - (id)removeAlarm:(MTMutableAlarm *)alarm
16 | {
17 | // delete the attributes for this given alarm
18 | [SLPrefsManager deleteAlarmForAlarmId:[alarm alarmIDString]];
19 |
20 | return %orig;
21 | }
22 |
23 | - (id)updateAlarm:(MTMutableAlarm *)alarm
24 | {
25 | // proceed to potentially update the alarm's Sleeper preferences if the update wasn't initiated by the tweak itself
26 | if (!alarm.SLWasUpdatedBySleeper) {
27 | // check if we have alarm preferences for this alarm
28 | NSString *alarmId = [alarm alarmIDString];
29 | SLAlarmPrefs *alarmPrefs = [SLPrefsManager alarmPrefsForAlarmId:alarmId];
30 | if (alarmPrefs && alarmPrefs.skipActivationStatus != kSLSkipActivatedStatusUnknown) {
31 | // reset the skip activation status for this alarm
32 | [SLPrefsManager setSkipActivatedStatusForAlarmId:alarmId
33 | skipActivatedStatus:kSLSkipActivatedStatusUnknown];
34 | } else if (!alarmPrefs) {
35 | alarmPrefs = [[SLAlarmPrefs alloc] initWithAlarmId:alarmId];
36 | [SLPrefsManager saveAlarmPrefs:alarmPrefs];
37 | }
38 | }
39 |
40 | return %orig;
41 | }
42 |
43 | %end
44 |
45 | %ctor {
46 | // only initialize this file for particular versions
47 | if (kSLSystemVersioniOS14 || kSLSystemVersioniOS13 || kSLSystemVersioniOS12) {
48 | %init();
49 | }
50 | }
--------------------------------------------------------------------------------
/core/SLMTAlarmStorage.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLMTAlarmStorage.x
3 | // Handles the modification of the snooze time for alarms on iOS 12 and iOS 13.
4 | //
5 | // Created by Joshua Seltzer on 3/20/2019.
6 | //
7 | //
8 |
9 | #import "../common/SLCompatibilityHelper.h"
10 |
11 | @interface MTAlarmStorage : NSObject
12 |
13 | // returns the currently active Sleep (i.e. "Wake Up") alarm (iOS 14)
14 | - (MTAlarm *)activeSleepAlarm;
15 |
16 | @end
17 |
18 | %hook MTAlarmStorage
19 |
20 | // invoked when an alarm is snoozed
21 | - (void)snoozeAlarmWithIdentifier:(NSString *)alarmId snoozeDate:(NSDate *)snoozeDate snoozeAction:(int)snoozeAction withCompletion:(id)completionHandler source:(id)source
22 | {
23 | // on iOS 14, the alarm ID for the "Wake Up" alarm might not be the same
24 | NSString *sleeperAlarmId = alarmId;
25 | if (kSLSystemVersioniOS14 && [[[self activeSleepAlarm] alarmIDString] isEqualToString:alarmId]) {
26 | sleeperAlarmId = [SLCompatibilityHelper wakeUpAlarmId];
27 | }
28 |
29 | // check to see if a modified snooze date is available for this alarm
30 | NSDate *modifiedSnoozeDate = [SLCompatibilityHelper modifiedSnoozeDateForAlarmId:sleeperAlarmId withOriginalDate:snoozeDate];
31 | if (modifiedSnoozeDate) {
32 | %orig(alarmId, modifiedSnoozeDate, snoozeAction, completionHandler, source);
33 | } else {
34 | %orig;
35 | }
36 | }
37 |
38 | %end
39 |
40 | %ctor {
41 | // only initialize this file for particular versions
42 | if (kSLSystemVersioniOS14 || kSLSystemVersioniOS13 || kSLSystemVersioniOS12) {
43 | %init();
44 | }
45 | }
--------------------------------------------------------------------------------
/core/SLMTUserNotificationCenter.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLMTUserNotificationCenter.x
3 | // Handles the posting of notifications for a scheduled alarm (iOS 12, iOS 13).
4 | //
5 | // Created by Joshua Seltzer on 3/20/2019.
6 | //
7 | //
8 |
9 | #import "../common/SLPrefsManager.h"
10 | #import "../common/SLAlarmPrefs.h"
11 | #import "../common/SLCompatibilityHelper.h"
12 |
13 | // trigger object which signifies why an alarm was fired
14 | @interface MTTrigger : NSObject
15 |
16 | // signifies whether or not this trigger is for an alert
17 | @property (readonly, nonatomic) BOOL isForAlert;
18 |
19 | // signifies whether or not this trigger is from snooze
20 | @property (readonly, nonatomic) BOOL isForSnooze;
21 |
22 | @end
23 |
24 | // protocol defining a schedulable object
25 | @protocol MTScheduleable
26 |
27 | // the identifier for the scheduleable object, which is the alarm Id in this case
28 | - (NSString *)identifier;
29 |
30 | @end
31 |
32 | // the scheduled object that will be fired when a notification is about to be posted
33 | @interface MTScheduledObject : NSObject
34 |
35 | // the trigger that invoked this scheduled object
36 | @property (copy, nonatomic) MTTrigger *trigger;
37 |
38 | // the schedulable object, which in this case is an MTAlarm object
39 | @property (copy, nonatomic) id scheduleable;
40 |
41 | @end
42 |
43 | %hook MTUserNotificationCenter
44 |
45 | // Invoked whenever the content for a scheduled alarm notification is going to be created. Override this function
46 | // to potentially set no content for the notification if we are to skip the alarm.
47 | + (void)_setSpecificContent:(UNMutableNotificationContent *)notificationContent forScheduledAlarm:(MTScheduledObject *)scheduledObject
48 | {
49 | // check to see if the alarm's trigger is an alert (as opposed to a snooze alert or snooze countdown)
50 | if (scheduledObject.trigger.isForAlert && !scheduledObject.trigger.isForSnooze && scheduledObject.scheduleable != nil) {
51 | // get the identifier for the scheduled object, which is in fact the alarm Id
52 | NSString *alarmId = [scheduledObject.scheduleable identifier];
53 |
54 | // on iOS 14, the alarm ID for the "Wake Up" alarm might not be the same
55 | NSString *sleeperAlarmId = alarmId;
56 | if (kSLSystemVersioniOS14 && [(MTAlarm *)scheduledObject.scheduleable isSleepAlarm]) {
57 | sleeperAlarmId = [SLCompatibilityHelper wakeUpAlarmId];
58 | }
59 |
60 | // get the sleeper alarm preferences for this alarm
61 | SLAlarmPrefs *alarmPrefs = [SLPrefsManager alarmPrefsForAlarmId:sleeperAlarmId];
62 | if (alarmPrefs) {
63 | // only activate the actual alarm if we should not be skipping this alarm
64 | if (![alarmPrefs shouldSkipToday]) {
65 | %orig;
66 | }
67 |
68 | // save the alarm's skip activation state to unknown for this alarm
69 | if (alarmPrefs.skipActivationStatus != kSLSkipActivatedStatusUnknown) {
70 | [SLPrefsManager setSkipActivatedStatusForAlarmId:sleeperAlarmId
71 | skipActivatedStatus:kSLSkipActivatedStatusUnknown];
72 | }
73 | } else {
74 | %orig;
75 | }
76 | } else {
77 | %orig;
78 | }
79 | }
80 |
81 | %end
82 |
83 | %ctor {
84 | // only initialize this file for particular versions
85 | if (kSLSystemVersioniOS14 || kSLSystemVersioniOS13 || kSLSystemVersioniOS12) {
86 | %init();
87 | }
88 | }
--------------------------------------------------------------------------------
/core/SLSBDashBoardLockScreenEnvironment.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLSBDashBoardLockScreenEnvironment.x
3 | // Hooks into this class allow for actions to be performed upon unlocking the device (iOS 13+).
4 | //
5 | // Created by Joshua Seltzer on 11/17/19.
6 | //
7 | //
8 |
9 | #import "../common/SLSkipAlarmAlertItem.h"
10 | #import "../common/SLAlarmPrefs.h"
11 | #import "../common/SLCompatibilityHelper.h"
12 |
13 | %hook SBDashBoardLockScreenEnvironment
14 |
15 | // iOS 13+: override to display a pop up allowing the user to skip an alarm
16 | - (void)prepareForUIUnlock
17 | {
18 | %orig;
19 |
20 | // check first to see if an existing skip alarm alert is being shown
21 | SBAlertItemsController *alertItemsController = (SBAlertItemsController *)[objc_getClass("SBAlertItemsController") sharedInstance];
22 | if (![alertItemsController hasAlertOfClass:objc_getClass("SLSkipAlarmAlertItem")]) {
23 | // get dates for today and tomorrow so we can properly determine if any of those alarms need to be skipped
24 | NSDate *today = [NSDate date];
25 | NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
26 | dateComponents.day = 1;
27 | NSCalendar *calendar = [NSCalendar currentCalendar];
28 | NSDate *tomorrow = [calendar dateByAddingComponents:dateComponents toDate:[calendar startOfDayForDate:today] options:0];
29 |
30 | // get the list of next alarms for today and tomorrow from the alarm manager
31 | MTAlarmManager *alarmManager = [[objc_getClass("MTAlarmManager") alloc] init];
32 | NSArray *nextAlarmsToday = [alarmManager nextAlarmsForDateSync:today maxCount:500 includeSleepAlarm:YES includeBedtimeNotification:NO];
33 | NSArray *nextAlarmsTomorrow = [alarmManager nextAlarmsForDateSync:tomorrow maxCount:500 includeSleepAlarm:YES includeBedtimeNotification:NO];
34 | NSArray *nextAlarms = [[NSOrderedSet orderedSetWithArray:[nextAlarmsToday arrayByAddingObjectsFromArray:nextAlarmsTomorrow]] array];
35 |
36 | // Iterate through the MTAlarm (and MTMutableAlarm) objects to see if any are skippable. The alarm objects should already be sorted.
37 | NSString *alarmTitle = nil;
38 | NSString *sleeperAlarmId = nil;
39 | NSDate *nextFireDate = nil;
40 | BOOL foundSkippableAlarm = NO;
41 | for (MTAlarm *alarm in nextAlarms) {
42 | // check first if this alarm is being snoozed
43 | if (!alarm.snoozed) {
44 | // on iOS 14, the alarm ID for the "Wake Up" alarm might not be the same
45 | sleeperAlarmId = [alarm alarmIDString];
46 | if (kSLSystemVersioniOS14 && [alarm isSleepAlarm]) {
47 | sleeperAlarmId = [SLCompatibilityHelper wakeUpAlarmId];
48 | }
49 |
50 | // check to see if this alarm is actually skippable
51 | nextFireDate = [alarm nextFireDateAfterDate:today includeBedtimeNotification:NO];
52 | BOOL isAlarmSkippable = [SLCompatibilityHelper isAlarmSkippableForAlarmId:sleeperAlarmId withNextFireDate:nextFireDate];
53 | if (isAlarmSkippable) {
54 | foundSkippableAlarm = YES;
55 | alarmTitle = [SLCompatibilityHelper alarmTitleForMTAlarm:alarm];
56 | break;
57 | }
58 | }
59 | }
60 | if (foundSkippableAlarm) {
61 | // after a slight delay, show an alert that will ask the user to skip the alarm on the main thread
62 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC));
63 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
64 | // create and display the custom alert item
65 | SLSkipAlarmAlertItem *alert = [[objc_getClass("SLSkipAlarmAlertItem") alloc] initWithTitle:alarmTitle
66 | alarmId:sleeperAlarmId
67 | nextFireDate:nextFireDate];
68 | [alertItemsController activateAlertItem:alert animated:YES];
69 | });
70 | }
71 | }
72 | }
73 |
74 | %end
75 |
76 | %ctor {
77 | // check which version we are running to determine which group to initialize
78 | if (kSLSystemVersioniOS14 || kSLSystemVersioniOS13) {
79 | %init();
80 | }
81 | }
--------------------------------------------------------------------------------
/core/SLSBLockScreenViewControllerBase.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLSBLockScreenViewControllerBase.x
3 | // Hooks into this class allow for actions to be performed upon unlocking the device (iOS 12).
4 | //
5 | // Created by Joshua Seltzer on 4/12/19.
6 | //
7 | //
8 |
9 | #import "../common/SLSkipAlarmAlertItem.h"
10 | #import "../common/SLCompatibilityHelper.h"
11 |
12 | %hook SBLockScreenViewControllerBase
13 |
14 | // iOS 12: override to display a pop up allowing the user to skip an alarm
15 | - (void)prepareForUIUnlock
16 | {
17 | %orig;
18 |
19 | // check first to see if an existing skip alarm alert is being shown
20 | SBAlertItemsController *alertItemsController = (SBAlertItemsController *)[objc_getClass("SBAlertItemsController") sharedInstance];
21 | if (![alertItemsController hasAlertOfClass:objc_getClass("SLSkipAlarmAlertItem")]) {
22 | // get dates for today and tomorrow so we can properly determine if any of those alarms need to be skipped
23 | NSDate *today = [NSDate date];
24 | NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
25 | dateComponents.day = 1;
26 | NSCalendar *calendar = [NSCalendar currentCalendar];
27 | NSDate *tomorrow = [calendar dateByAddingComponents:dateComponents toDate:[calendar startOfDayForDate:today] options:0];
28 |
29 | // get the list of next alarms for today and tomorrow from the alarm manager
30 | MTAlarmManager *alarmManager = [[objc_getClass("MTAlarmManager") alloc] init];
31 | NSArray *nextAlarmsToday = [alarmManager nextAlarmsForDateSync:today maxCount:500 includeSleepAlarm:YES includeBedtimeNotification:NO];
32 | NSArray *nextAlarmsTomorrow = [alarmManager nextAlarmsForDateSync:tomorrow maxCount:500 includeSleepAlarm:YES includeBedtimeNotification:NO];
33 | NSArray *nextAlarms = [[NSOrderedSet orderedSetWithArray:[nextAlarmsToday arrayByAddingObjectsFromArray:nextAlarmsTomorrow]] array];
34 |
35 | // Iterate through the MTAlarm (and MTMutableAlarm) objects to see if any are skippable. The alarm objects should already be sorted.
36 | NSString *alarmTitle = nil;
37 | NSString *alarmId = nil;
38 | NSDate *nextFireDate = nil;
39 | BOOL foundSkippableAlarm = NO;
40 | for (MTAlarm *alarm in nextAlarms) {
41 | // check first if this alarm is being snoozed
42 | if (!alarm.snoozed) {
43 | alarmId = [alarm alarmIDString];
44 | nextFireDate = [alarm nextFireDateAfterDate:today includeBedtimeNotification:NO];
45 | BOOL isAlarmSkippable = [SLCompatibilityHelper isAlarmSkippableForAlarmId:alarmId withNextFireDate:nextFireDate];
46 | if (isAlarmSkippable) {
47 | foundSkippableAlarm = YES;
48 | alarmTitle = [SLCompatibilityHelper alarmTitleForMTAlarm:alarm];
49 | break;
50 | }
51 | }
52 | }
53 | if (foundSkippableAlarm) {
54 | // after a slight delay, show an alert that will ask the user to skip the alarm on the main thread
55 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC));
56 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
57 | // create and display the custom alert item
58 | SLSkipAlarmAlertItem *alert = [[objc_getClass("SLSkipAlarmAlertItem") alloc] initWithTitle:alarmTitle
59 | alarmId:alarmId
60 | nextFireDate:nextFireDate];
61 | [alertItemsController activateAlertItem:alert animated:YES];
62 | });
63 | }
64 | }
65 | }
66 |
67 | %end
68 |
69 | %ctor {
70 | // check which version we are running to determine which group to initialize
71 | if (kSLSystemVersioniOS12) {
72 | %init();
73 | }
74 | }
--------------------------------------------------------------------------------
/core_legacy/SLAlarmManager.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLAlarmManager.x
3 | // Modify Apple's internal class for managing alarms.
4 | //
5 | // Created by Joshua Seltzer on 2/22/17.
6 | //
7 | //
8 |
9 | #import "../common/SLCompatibilityHelper.h"
10 | #import "../common/SLPrefsManager.h"
11 |
12 | // utilized in iOS 8, iOS 9, iOS 10, and iOS 11
13 | %hook AlarmManager
14 |
15 | - (void)removeAlarm:(Alarm *)alarm
16 | {
17 | %orig;
18 |
19 | // delete the attributes for this given alarm
20 | [SLPrefsManager deleteAlarmForAlarmId:[SLCompatibilityHelper alarmIdForAlarm:alarm]];
21 | }
22 |
23 | - (void)setAlarm:(Alarm *)alarm active:(BOOL)active
24 | {
25 | %orig;
26 |
27 | // get the alarm Id for the alarm
28 | NSString *alarmId = [SLCompatibilityHelper alarmIdForAlarm:alarm];
29 |
30 | // check if we have alarm preferences for this alarm
31 | SLAlarmPrefs *alarmPrefs = [SLPrefsManager alarmPrefsForAlarmId:alarmId];
32 | if (alarmPrefs && alarmPrefs.skipActivationStatus != kSLSkipActivatedStatusUnknown) {
33 | // reset the skip activation status for this alarm
34 | [SLPrefsManager setSkipActivatedStatusForAlarmId:alarmId
35 | skipActivatedStatus:kSLSkipActivatedStatusUnknown];
36 | } else if (!alarmPrefs) {
37 | alarmPrefs = [[SLAlarmPrefs alloc] initWithAlarmId:alarmId];
38 | [SLPrefsManager saveAlarmPrefs:alarmPrefs];
39 | }
40 | }
41 |
42 | %end
43 |
44 | %ctor {
45 | // only initialize this file if we are on iOS 8, iOS 9, iOS 10, or iOS 11
46 | if (kSLSystemVersioniOS8 || kSLSystemVersioniOS9 || kSLSystemVersioniOS10 || kSLSystemVersioniOS11) {
47 | %init();
48 | }
49 | }
--------------------------------------------------------------------------------
/core_legacy/SLSBApplication.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLSBApplication.x
3 | // Hook into the SBApplication class to modify the snooze notification on iOS 8.
4 | //
5 | // Created by Joshua Seltzer on 2/23/17.
6 | //
7 | //
8 |
9 | #import "../common/SLCompatibilityHelper.h"
10 |
11 | %hook SBApplication
12 |
13 | // iOS 8: override to insert our custom snooze time if it was defined
14 | - (void)scheduleSnoozeNotification:(UIConcreteLocalNotification *)notification
15 | {
16 | // attempt to modify the notification with a custom snooze time
17 | [SLCompatibilityHelper modifySnoozeNotificationForLocalNotification:notification];
18 |
19 | %orig;
20 | }
21 |
22 | %end
23 |
24 | %ctor {
25 | // only initialize this file if we are on iOS 8
26 | if (kSLSystemVersioniOS8) {
27 | %init();
28 | }
29 | }
--------------------------------------------------------------------------------
/core_legacy/SLSBClockDataProvider.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLSBClockDataProvider.x
3 | // Hook into the SBClockDataProvider class to potentially skip an alarm notification.
4 | //
5 | // Created by Joshua Seltzer on 2/23/17.
6 | //
7 | //
8 |
9 | #import "../common/SLCompatibilityHelper.h"
10 | #import "../common/SLPrefsManager.h"
11 |
12 | %group iOS10iOS11
13 |
14 | %hook SBClockDataProvider
15 |
16 | // iOS 10 / iOS 11: invoked when an alarm alert (i.e. bulletin) is about to be displayed
17 | - (void)_publishBulletinForNotification:(UNNotification *)notification
18 | {
19 | // grab the shared instance of the clock data provider
20 | SBClockDataProvider *clockDataProvider = [objc_getClass("SBClockDataProvider") sharedInstance];
21 |
22 | // check to see if this notification is an alarm notification
23 | if ([clockDataProvider _isAlarmNotification:notification]) {
24 | // get the alarm Id from the notification
25 | NSString *alarmId = [clockDataProvider _alarmIDFromNotificationRequest:notification.request];
26 |
27 | // get the sleeper alarm preferences for this alarm
28 | SLAlarmPrefs *alarmPrefs = [SLPrefsManager alarmPrefsForAlarmId:alarmId];
29 | if (alarmPrefs) {
30 | // only activate the actual alarm if we should not be skipping this alarm
31 | if (![alarmPrefs shouldSkipToday]) {
32 | %orig;
33 | }
34 |
35 | // save the alarm's skip activation state to unknown for this alarm
36 | if (alarmPrefs.skipActivationStatus != kSLSkipActivatedStatusUnknown) {
37 | [SLPrefsManager setSkipActivatedStatusForAlarmId:alarmId
38 | skipActivatedStatus:kSLSkipActivatedStatusUnknown];
39 | }
40 | } else {
41 | %orig;
42 | }
43 | } else {
44 | %orig;
45 | }
46 | }
47 |
48 | %end
49 |
50 | %end // %group iOS10iOS11
51 |
52 | %group iOS8iOS9
53 |
54 | %hook SBClockDataProvider
55 |
56 | // iOS 8 / iOS 9: invoked when an alarm alert (i.e. bulletin) is about to be displayed
57 | - (void)_publishBulletinForLocalNotification:(UIConcreteLocalNotification *)notification
58 | {
59 | // grab the shared instance of the clock data provider
60 | SBClockDataProvider *clockDataProvider = [objc_getClass("SBClockDataProvider") sharedInstance];
61 |
62 | // check to see if this notification is an alarm notification
63 | if ([clockDataProvider _isAlarmNotification:notification]) {
64 | // get the alarm Id from the notification
65 | NSString *alarmId = [clockDataProvider _alarmIDFromNotification:notification];
66 |
67 | // get the sleeper alarm preferences for this alarm
68 | SLAlarmPrefs *alarmPrefs = [SLPrefsManager alarmPrefsForAlarmId:alarmId];
69 | if (alarmPrefs) {
70 | // check to see if this alarm should be skipped
71 | if ([alarmPrefs shouldSkipToday]) {
72 | // grab the alarm that we are going to ask to skip from the shared alarm manager
73 | AlarmManager *alarmManager = (AlarmManager *)[objc_getClass("AlarmManager") sharedManager];
74 | [alarmManager loadAlarms];
75 | Alarm *alarm = [alarmManager alarmWithId:alarmId];
76 |
77 | // simulate the alarm going off
78 | [alarm handleAlarmFired:notification];
79 | [alarmManager handleNotificationFired:notification];
80 | } else {
81 | %orig;
82 | }
83 |
84 | // save the alarm's skip activation state to unknown for this alarm
85 | if (alarmPrefs.skipActivationStatus != kSLSkipActivatedStatusUnknown) {
86 | [SLPrefsManager setSkipActivatedStatusForAlarmId:alarmId
87 | skipActivatedStatus:kSLSkipActivatedStatusUnknown];
88 | }
89 | } else {
90 | %orig;
91 | }
92 | } else {
93 | %orig;
94 | }
95 | }
96 |
97 | %end
98 |
99 | %end // %group iOS8iOS9
100 |
101 | %ctor {
102 | // check which version we are running to determine which group to initialize
103 | if (kSLSystemVersioniOS10 || kSLSystemVersioniOS11) {
104 | %init(iOS10iOS11);
105 | } else if (kSLSystemVersioniOS8 || kSLSystemVersioniOS9) {
106 | %init(iOS8iOS9);
107 | }
108 | }
--------------------------------------------------------------------------------
/core_legacy/SLSBLockScreenManager.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLSBLockScreenManager.x
3 | // Hook into the SBLockScreenManager class to potentially show an alert after unlocking the device.
4 | //
5 | // Created by Joshua Seltzer on 2/23/17.
6 | //
7 | //
8 |
9 | #import "../common/SLSkipAlarmAlertItem.h"
10 | #import "../common/SLCompatibilityHelper.h"
11 |
12 | %hook SBLockScreenManager
13 |
14 | // iOS 10: override to display a pop up allowing the user to skip an alarm
15 | - (void)_finishUIUnlockFromSource:(int)source withOptions:(id)options
16 | {
17 | %orig;
18 |
19 | // check first to see if an existing skip alarm alert is being shown
20 | SBAlertItemsController *alertItemsController = (SBAlertItemsController *)[objc_getClass("SBAlertItemsController") sharedInstance];
21 | if (![alertItemsController hasAlertOfClass:objc_getClass("SLSkipAlarmAlertItem")]) {
22 | // create the block that will be used to inspect the notification requests from the clock notification manager
23 | void (^clockNotificationManagerNotificationRequests) (NSArray *) = ^(NSArray *notificationRequests) {
24 | // only continue if valid notification requests were returned
25 | if (notificationRequests.count > 0) {
26 | // attempt to get the next skippable alarm notification request from the notification requests returned
27 | UNNotificationRequest *nextAlarmNotificationRequest = [SLCompatibilityHelper nextSkippableAlarmNotificationRequestForNotificationRequests:notificationRequests];
28 |
29 | // if we found a valid alarm, check to see if we should ask to skip it
30 | if (nextAlarmNotificationRequest != nil) {
31 | // grab the shared instance of the clock data provider
32 | SBClockDataProvider *clockDataProvider = [objc_getClass("SBClockDataProvider") sharedInstance];
33 |
34 | // grab the alarm Id for this notification request
35 | NSString *alarmId = [clockDataProvider _alarmIDFromNotificationRequest:nextAlarmNotificationRequest];
36 |
37 | // grab the shared instance of the alarm manager, load the alarms, and get the alarm object
38 | // that is associated with this notification request
39 | AlarmManager *alarmManager = (AlarmManager *)[objc_getClass("AlarmManager") sharedManager];
40 | [alarmManager loadAlarms];
41 | Alarm *alarm = [alarmManager alarmWithId:alarmId];
42 |
43 | // after a slight delay, show an alert that will ask the user to skip the alarm on the main thread
44 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC));
45 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
46 | // get the fire date of the alarm we are going to display
47 | NSDate *nextTriggerDate = [((UNLegacyNotificationTrigger *)nextAlarmNotificationRequest.trigger) _nextTriggerDateAfterDate:[NSDate date]
48 | withRequestedDate:nil
49 | defaultTimeZone:[NSTimeZone localTimeZone]];
50 |
51 | // create and display the custom alert item
52 | SLSkipAlarmAlertItem *alert = [[objc_getClass("SLSkipAlarmAlertItem") alloc] initWithTitle:[SLCompatibilityHelper alarmTitleForAlarm:alarm]
53 | alarmId:alarmId
54 | nextFireDate:nextTriggerDate];
55 | [alertItemsController activateAlertItem:alert animated:YES];
56 | });
57 | }
58 | }
59 | };
60 |
61 | // get the clock notification manager and get the notification requests
62 | SBClockNotificationManager *clockNotificationManager = [objc_getClass("SBClockNotificationManager") sharedInstance];
63 | [clockNotificationManager getPendingNotificationRequestsWithCompletionHandler:clockNotificationManagerNotificationRequests];
64 | }
65 | }
66 |
67 | %end
68 |
69 | %ctor {
70 | if (kSLSystemVersioniOS10) {
71 | %init();
72 | }
73 | }
--------------------------------------------------------------------------------
/core_legacy/SLSBLockScreenViewController.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLSBLockScreenViewController.x
3 | // Hook into the SBLockScreenViewController class to potentially show an alert after unlocking the device for iOS 8 or iOS 9.
4 | //
5 | // Created by Joshua Seltzer on 2/23/17.
6 | //
7 | //
8 |
9 | #import "../common/SLSkipAlarmAlertItem.h"
10 | #import "../common/SLCompatibilityHelper.h"
11 |
12 | %hook SBLockScreenViewController
13 |
14 | // iOS 8 / iOS 9: override to display a pop up allowing the user to skip an alarm
15 | - (void)finishUIUnlockFromSource:(int)source
16 | {
17 | %orig;
18 |
19 | // check first to see if an existing skip alarm alert is being shown
20 | SBAlertItemsController *alertItemsController = (SBAlertItemsController *)[objc_getClass("SBAlertItemsController") sharedInstance];
21 | if (![alertItemsController hasAlertOfClass:objc_getClass("SLSkipAlarmAlertItem")]) {
22 | // grab the shared instance of the clock data provider
23 | SBClockDataProvider *clockDataProvider = [objc_getClass("SBClockDataProvider") sharedInstance];
24 |
25 | // attempt to get the next skippable alarm notification
26 | UIConcreteLocalNotification *nextAlarmNotification = [SLCompatibilityHelper nextSkippableAlarmLocalNotification];
27 |
28 | // if we found a valid alarm, check to see if we should ask to skip it
29 | if (nextAlarmNotification != nil) {
30 | // grab the alarm Id for this notification
31 | NSString *alarmId = [clockDataProvider _alarmIDFromNotification:nextAlarmNotification];
32 |
33 | // grab the shared instance of the alarm manager and load the alarms
34 | AlarmManager *alarmManager = (AlarmManager *)[objc_getClass("AlarmManager") sharedManager];
35 | [alarmManager loadAlarms];
36 | Alarm *alarm = [alarmManager alarmWithId:alarmId];
37 |
38 | // after a slight delay, show an alert that will ask the user to skip the alarm
39 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC));
40 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
41 | // get the fire date of the alarm we are going to display
42 | NSDate *alarmFireDate = [nextAlarmNotification nextFireDateAfterDate:[NSDate date]
43 | localTimeZone:[NSTimeZone localTimeZone]];
44 |
45 | // create and display the custom alert item
46 | SLSkipAlarmAlertItem *alert = [[objc_getClass("SLSkipAlarmAlertItem") alloc] initWithTitle:[SLCompatibilityHelper alarmTitleForAlarm:alarm]
47 | alarmId:alarmId
48 | nextFireDate:alarmFireDate];
49 | [alertItemsController activateAlertItem:alert animated:YES];
50 | });
51 | }
52 | }
53 | }
54 |
55 | %end
56 |
57 | %ctor {
58 | // only initialize this file if we are on iOS 8 or iOS 9
59 | if (kSLSystemVersioniOS8 || kSLSystemVersioniOS9) {
60 | %init();
61 | }
62 | }
--------------------------------------------------------------------------------
/core_legacy/SLSBLockScreenViewControllerBase.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLSBLockScreenViewControllerBase.x
3 | // Hooks into this class allow for actions to be performed upon unlocking the device (iOS 11).
4 | //
5 | // Created by Joshua Seltzer on 4/12/19.
6 | //
7 | //
8 |
9 | #import "../common/SLSkipAlarmAlertItem.h"
10 | #import "../common/SLCompatibilityHelper.h"
11 |
12 | %hook SBLockScreenViewControllerBase
13 |
14 | // iOS 11: override to display a pop up allowing the user to skip an alarm
15 | - (void)prepareForUIUnlock
16 | {
17 | // check first to see if an existing skip alarm alert is being shown
18 | SBAlertItemsController *alertItemsController = (SBAlertItemsController *)[objc_getClass("SBAlertItemsController") sharedInstance];
19 | if (![alertItemsController hasAlertOfClass:objc_getClass("SLSkipAlarmAlertItem")]) {
20 | // create the block that will be used to inspect the notification requests from the clock notification manager
21 | void (^clockNotificationManagerNotificationRequests) (NSArray *) = ^(NSArray *notificationRequests) {
22 | // only continue if valid notification requests were returned
23 | if (notificationRequests.count > 0) {
24 | // attempt to get the next skippable alarm notification request from the notification requests returned
25 | UNNotificationRequest *nextAlarmNotificationRequest = [SLCompatibilityHelper nextSkippableAlarmNotificationRequestForNotificationRequests:notificationRequests];
26 |
27 | // if we found a valid alarm, check to see if we should ask to skip it
28 | if (nextAlarmNotificationRequest != nil) {
29 | // grab the shared instance of the clock data provider
30 | SBClockDataProvider *clockDataProvider = [objc_getClass("SBClockDataProvider") sharedInstance];
31 |
32 | // grab the alarm Id for this notification request
33 | NSString *alarmId = [clockDataProvider _alarmIDFromNotificationRequest:nextAlarmNotificationRequest];
34 |
35 | // grab the shared instance of the alarm manager, load the alarms, and get the alarm object
36 | // that is associated with this notification request
37 | AlarmManager *alarmManager = (AlarmManager *)[objc_getClass("AlarmManager") sharedManager];
38 | [alarmManager loadAlarms];
39 | Alarm *alarm = [alarmManager alarmWithId:alarmId];
40 |
41 | // after a slight delay, show an alert that will ask the user to skip the alarm on the main thread
42 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC));
43 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
44 | // get the fire date of the alarm we are going to display
45 | NSDate *nextTriggerDate = [((UNLegacyNotificationTrigger *)nextAlarmNotificationRequest.trigger) _nextTriggerDateAfterDate:[NSDate date]
46 | withRequestedDate:nil
47 | defaultTimeZone:[NSTimeZone localTimeZone]];
48 |
49 | // create and display the custom alert item
50 | SLSkipAlarmAlertItem *alert = [[objc_getClass("SLSkipAlarmAlertItem") alloc] initWithTitle:[SLCompatibilityHelper alarmTitleForAlarm:alarm]
51 | alarmId:alarmId
52 | nextFireDate:nextTriggerDate];
53 | [alertItemsController activateAlertItem:alert animated:YES];
54 | });
55 | }
56 | }
57 | };
58 |
59 | // get the clock notification manager and get the notification requests
60 | SBClockNotificationManager *clockNotificationManager = [objc_getClass("SBClockNotificationManager") sharedInstance];
61 | [clockNotificationManager getPendingNotificationRequestsWithCompletionHandler:clockNotificationManagerNotificationRequests];
62 | }
63 | }
64 |
65 | %end
66 |
67 | %ctor {
68 | // check which version we are running to determine which group to initialize
69 | if (kSLSystemVersioniOS11) {
70 | %init();
71 | }
72 | }
--------------------------------------------------------------------------------
/core_legacy/SLUNLocalNotificationClient.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLUNLocalNotificationClient.x
3 | // Hook into the UNLocalNotificationClient class to modify the snooze notification on iOS 9.
4 | //
5 | // Created by Joshua Seltzer on 2/23/17.
6 | //
7 | //
8 |
9 | #import "../common/SLCompatibilityHelper.h"
10 |
11 | %hook UNLocalNotificationClient
12 |
13 | // iOS 9: override to insert our custom snooze time if it was defined
14 | - (void)scheduleSnoozeNotification:(UIConcreteLocalNotification *)notification
15 | {
16 | // attempt to modify the notification with a custom snooze time
17 | [SLCompatibilityHelper modifySnoozeNotificationForLocalNotification:notification];
18 |
19 | %orig;
20 | }
21 |
22 | %end
23 |
24 | %ctor {
25 | // only initialize this file if we are on iOS 9
26 | if (kSLSystemVersioniOS9) {
27 | %init();
28 | }
29 | }
--------------------------------------------------------------------------------
/core_legacy/SLUNSNotificationSchedulingService.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLUNSNotificationSchedulingService.x
3 | // Hook into the UNSNotificationSchedulingService class to modify the snooze notification on iOS 10 and iOS 11.
4 | //
5 | // Created by Joshua Seltzer on 2/23/17.
6 | //
7 | //
8 |
9 | #import "../common/SLCompatibilityHelper.h"
10 |
11 | %hook UNSNotificationSchedulingService
12 |
13 | // iOS 10 / iOS 11: function that adds new notification records to the scheduling service
14 | - (void)addPendingNotificationRecords:(NSArray *)notificationRecords forBundleIdentifier:(NSString *)bundleId withCompletionHandler:(id)completionHandler
15 | {
16 | // check to see if the notification is for the timer application
17 | if ([bundleId isEqualToString:@"com.apple.mobiletimer"]) {
18 | // iterate through the notification records
19 | for (UNSNotificationRecord *notification in notificationRecords) {
20 | // check to see if the notification is a snooze notification
21 | if ([notification isFromSnooze]) {
22 | // modify the snooze notifications with the updated snooze times
23 | [SLCompatibilityHelper modifySnoozeNotificationForNotificationRecord:notification];
24 | }
25 | }
26 | }
27 |
28 | %orig;
29 | }
30 |
31 | %end
32 |
33 | %ctor {
34 | // only initialize this file if we are on iOS 10 or iOS 11
35 | if (kSLSystemVersioniOS10 || kSLSystemVersioniOS11) {
36 | %init();
37 | }
38 | }
--------------------------------------------------------------------------------
/holiday_gen.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import sys
4 | import os
5 | import re
6 | import datetime
7 | import holidays
8 | import plistlib
9 |
10 | # years which will be generated for any given country
11 | START_YEAR = 2023
12 | END_YEAR = 2050
13 |
14 | # constants used to modify holidays upon generation
15 | OBSERVED_TEXT = "(Observed)"
16 | THANKSGIVING_TEXT = "Thanksgiving"
17 | DAY_AFTER_THANKSGIVING_TEXT = "Day After Thanksgiving"
18 | MARTIN_LUTHER_KING_JR_TEXT = "Martin Luther King, Jr. Day"
19 | CHRISTMAS_DAY_TEXT = "Christmas Day"
20 | CHRISTMAS_EVE_TEXT = "Christmas Eve"
21 | NEW_YEARS_DAY_TEXT = "New Year's Day"
22 | NEW_YEARS_EVE_TEXT = "New Year's Eve"
23 |
24 | # path to the Sleeper bundle which is used to store the holidays and localized strings
25 | SLEEPER_BUNDLE_PATH = "layout/Library/Application Support/Sleeper.bundle"
26 |
27 | # names of the keys that will be used when creating the plist
28 | DATE_CREATED_KEY = "dateCreated"
29 | HOLIDAYS_KEY = "holidays"
30 | NAME_KEY = "name"
31 | DATES_KEY = "dates"
32 |
33 | # entry point for creating the holidays for a particular country
34 | def gen_country_holidays(country_code):
35 | print("Generating holiday plist file for \"{0}\" from years {1} to {2}.".format(country_code, START_YEAR, END_YEAR))
36 |
37 | # define the high-level plist file and holiday mapping which will be generated for this country
38 | country_holidays = []
39 | holiday_map = {}
40 |
41 | # iterate through each year one by one
42 | years = list(range(START_YEAR, END_YEAR))
43 | for year in years:
44 | # generate the list of holidays for the given country code (if valid) for the iterated year
45 | try:
46 | global holidays_for_year
47 | exec("holidays_for_year = holidays.{0}(observed=True, expand=False, years=[{1}])".format(country_code, year), globals())
48 | except AttributeError:
49 | print("Entered invalid country code, exiting.")
50 | exit(1)
51 |
52 | if year == START_YEAR:
53 | print(holidays_for_year)
54 | print("This country has {0} holidays.".format(len(holidays_for_year)))
55 |
56 | # iterate through the generated holidays to potentially remove holidays
57 | holidays_to_remove = []
58 | for date, name in holidays_for_year.items():
59 | # mark any non-observed holidays for removal
60 | if OBSERVED_TEXT in name:
61 | holiday_to_remove = name.replace(OBSERVED_TEXT, "").strip()
62 | holidays_to_remove.append(holiday_to_remove)
63 | print("Attempting to remove holiday \"{0}\" since this is an observed holiday in {1}.".format(holiday_to_remove, year))
64 | holidays_for_year = {date:name.replace(OBSERVED_TEXT, "").strip() for date, name in holidays_for_year.items() if name not in holidays_to_remove or date.weekday() < 5}
65 |
66 | if year == START_YEAR:
67 | print("After removing observed holidays, this country has {0} holidays.".format(len(holidays_for_year)))
68 |
69 | # add additional holidays for particular countries
70 | holidays_for_year.update(generate_additional_holidays(country_code, year, holidays_for_year))
71 |
72 | # final pass of the holidays for the given year to add them to the plist
73 | for date, combined_names in sorted(holidays_for_year.items()):
74 | # remove some extra text in between brackets from the name
75 | combined_names = re.sub(r"\[.*?\]", "", combined_names)
76 |
77 | # check to see if the name needs to be split (the holidays library will combine the same dates with a combined name)
78 | for name in combined_names.split(', '):
79 | # remove any additional leading and trailing whitespace
80 | name = name.strip()
81 |
82 | # update the holiday map with the added holiday
83 | date_time = datetime.datetime.combine(date, datetime.time(0, 0)).astimezone(datetime.timezone.utc)
84 | dates = holiday_map.get(name)
85 | if not dates:
86 | dates = [date_time]
87 | elif date_time not in dates:
88 | dates.append(date_time)
89 | holiday_map.update({name:dates})
90 |
91 | # get the current datetime in UTC timezone
92 | now = datetime.datetime.now().astimezone(datetime.timezone.utc)
93 |
94 | # generate the plist
95 | for name in holiday_map.keys():
96 | # get all of the parts for the dictionary that will be added to the plist
97 | dates = holiday_map.get(name)
98 |
99 | # convert the datetime objects to date strings and remove any past dates
100 | date_strings = []
101 | for date in dates:
102 | if date >= now:
103 | date_strings.append(date.strftime('%Y-%m-%d'))
104 |
105 | # add a new entry to the plist
106 | country_holidays.append({NAME_KEY:name, DATES_KEY:date_strings})
107 |
108 | # create the root of the plist
109 | plist_root = {DATE_CREATED_KEY:now, "holidays":country_holidays}
110 |
111 | # write the final plist to file
112 | plist_file_path = os.path.join(SLEEPER_BUNDLE_PATH, "{0}_holidays.plist".format(country_code.lower()))
113 | with open(plist_file_path, 'wb') as fp:
114 | plistlib.dump(plist_root, fp, sort_keys=False)
115 |
116 | print("Wrote results to file: {0}".format(plist_file_path))
117 | print("Holiday list generation completed for \"{0}\" from years {1} to {2}.".format(country_code, START_YEAR, END_YEAR))
118 |
119 | # creates new holidays for particular countries
120 | def generate_additional_holidays(country_code, year, holidays_for_year):
121 | new_holidays = {}
122 |
123 | if country_code == 'US':
124 | # add new holidays which have different dates each year
125 | for date, name in holidays_for_year.items():
126 | if THANKSGIVING_TEXT in name:
127 | print("Adding additional holiday, \"{0}\" for {1}.".format(DAY_AFTER_THANKSGIVING_TEXT, year))
128 | new_holidays.update({date + datetime.timedelta(days=1):DAY_AFTER_THANKSGIVING_TEXT})
129 |
130 | if MARTIN_LUTHER_KING_JR_TEXT in name:
131 | print("Fixing Martin Luther King Jr. Day")
132 | new_holidays.update({date:"Martin Luther King Jr. Day"})
133 |
134 | # add New Year's Eve and Christmas Eve which are static each year
135 | print("Adding additional holiday, \"{0}\" for {1}.".format(CHRISTMAS_EVE_TEXT, year))
136 | print("Adding additional holiday, \"{0}\" for {1}.".format(NEW_YEARS_EVE_TEXT, year))
137 | new_holidays.update({datetime.date(year, 12, 24):CHRISTMAS_EVE_TEXT, datetime.date(year, 12, 31):NEW_YEARS_EVE_TEXT})
138 |
139 | return new_holidays
140 |
141 | if __name__== "__main__":
142 | if len(sys.argv) == 2:
143 | # generate the plist
144 | gen_country_holidays(sys.argv[1])
145 | else:
146 | print("Incorrect usage! Please supply a valid country code.")
--------------------------------------------------------------------------------
/layout/DEBIAN/postinst:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo "Sleeper (postinst): Killing mobiletimerd"
4 | killall -9 mobiletimerd
5 | exit 0
6 |
--------------------------------------------------------------------------------
/layout/DEBIAN/postrm:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo "Sleeper (postrm): Killing mobiletimerd"
4 | killall -9 mobiletimerd
5 | exit 0
6 |
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/ar.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Arabic (translation provided by MiRO92)
10 | "SNOOZE_TIME" = "وقت الغفوة";
11 | "HOURS" = "ساعة";
12 | "MINUTES" = "دقيقة";
13 | "SECONDS" = "ثانية";
14 | "RESET_DEFAULT" = "إعادة التعيين إلى الإفتراضي";
15 | "DEFAULT_SNOOZE_TIME" = "وقت الغفوة الإفتراضي هو %@.";
16 | "SKIP" = "تخطي رنين المنبه";
17 | "SKIP_TIME" = "اختر وقت لـ(تخطي رنين المنبه)";
18 | "SKIP_ALARM" = "تخطي المنبه";
19 | "SKIP_QUESTION" = "هل تريد تخطي \"%@\" المقرر له أن يرن في %@؟";
20 | "SKIP_TIME_EXPLANATION" = "إختر المدة التي سيتم فيها إظهار تنبيه لـ(تخطي رنين المنبه) قبل وقت رنين المنبه.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/au_holidays.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | dateCreated
6 | 2019-10-20T20:33:04Z
7 | holidays
8 |
9 |
10 | name
11 | New Year's Day
12 | dates
13 |
14 | 2025-01-01
15 | 2026-01-01
16 | 2027-01-01
17 | 2028-01-03
18 | 2029-01-01
19 | 2030-01-01
20 | 2031-01-01
21 | 2032-01-01
22 | 2033-01-03
23 | 2034-01-02
24 | 2035-01-01
25 | 2036-01-01
26 | 2037-01-01
27 | 2038-01-01
28 | 2039-01-03
29 | 2040-01-02
30 | 2041-01-01
31 | 2042-01-01
32 | 2043-01-01
33 | 2044-01-01
34 | 2045-01-02
35 | 2046-01-01
36 | 2047-01-01
37 | 2048-01-01
38 | 2049-01-01
39 |
40 |
41 |
42 | name
43 | Australia Day
44 | dates
45 |
46 | 2025-01-27
47 | 2026-01-26
48 | 2027-01-26
49 | 2028-01-26
50 | 2029-01-26
51 | 2030-01-28
52 | 2031-01-27
53 | 2032-01-26
54 | 2033-01-26
55 | 2034-01-26
56 | 2035-01-26
57 | 2036-01-28
58 | 2037-01-26
59 | 2038-01-26
60 | 2039-01-26
61 | 2040-01-26
62 | 2041-01-28
63 | 2042-01-27
64 | 2043-01-26
65 | 2044-01-26
66 | 2045-01-26
67 | 2046-01-26
68 | 2047-01-28
69 | 2048-01-27
70 | 2049-01-26
71 |
72 |
73 |
74 | name
75 | Good Friday
76 | dates
77 |
78 | 2024-03-29
79 | 2025-04-18
80 | 2026-04-03
81 | 2027-03-26
82 | 2028-04-14
83 | 2029-03-30
84 | 2030-04-19
85 | 2031-04-11
86 | 2032-03-26
87 | 2033-04-15
88 | 2034-04-07
89 | 2035-03-23
90 | 2036-04-11
91 | 2037-04-03
92 | 2038-04-23
93 | 2039-04-08
94 | 2040-03-30
95 | 2041-04-19
96 | 2042-04-04
97 | 2043-03-27
98 | 2044-04-15
99 | 2045-04-07
100 | 2046-03-23
101 | 2047-04-12
102 | 2048-04-03
103 | 2049-04-16
104 |
105 |
106 |
107 | name
108 | Easter Monday
109 | dates
110 |
111 | 2024-04-01
112 | 2025-04-21
113 | 2026-04-06
114 | 2027-03-29
115 | 2028-04-17
116 | 2029-04-02
117 | 2030-04-22
118 | 2031-04-14
119 | 2032-03-29
120 | 2033-04-18
121 | 2034-04-10
122 | 2035-03-26
123 | 2036-04-14
124 | 2037-04-06
125 | 2038-04-26
126 | 2039-04-11
127 | 2040-04-02
128 | 2041-04-22
129 | 2042-04-07
130 | 2043-03-30
131 | 2044-04-18
132 | 2045-04-10
133 | 2046-03-26
134 | 2047-04-15
135 | 2048-04-06
136 | 2049-04-19
137 |
138 |
139 |
140 | name
141 | Anzac Day
142 | dates
143 |
144 | 2024-04-25
145 | 2025-04-25
146 | 2026-04-25
147 | 2027-04-25
148 | 2028-04-25
149 | 2029-04-25
150 | 2030-04-25
151 | 2031-04-25
152 | 2032-04-25
153 | 2033-04-25
154 | 2034-04-25
155 | 2035-04-25
156 | 2036-04-25
157 | 2037-04-25
158 | 2038-04-25
159 | 2039-04-25
160 | 2040-04-25
161 | 2041-04-25
162 | 2042-04-25
163 | 2043-04-25
164 | 2044-04-25
165 | 2045-04-25
166 | 2046-04-25
167 | 2047-04-25
168 | 2048-04-25
169 | 2049-04-25
170 |
171 |
172 |
173 | name
174 | Christmas Day
175 | dates
176 |
177 | 2024-12-25
178 | 2025-12-25
179 | 2026-12-25
180 | 2027-12-27
181 | 2028-12-25
182 | 2029-12-25
183 | 2030-12-25
184 | 2031-12-25
185 | 2032-12-27
186 | 2033-12-27
187 | 2034-12-25
188 | 2035-12-25
189 | 2036-12-25
190 | 2037-12-25
191 | 2038-12-27
192 | 2039-12-27
193 | 2040-12-25
194 | 2041-12-25
195 | 2042-12-25
196 | 2043-12-25
197 | 2044-12-27
198 | 2045-12-25
199 | 2046-12-25
200 | 2047-12-25
201 | 2048-12-25
202 | 2049-12-27
203 |
204 |
205 |
206 | name
207 | Boxing Day
208 | dates
209 |
210 | 2024-12-26
211 | 2025-12-26
212 | 2026-12-28
213 | 2027-12-28
214 | 2028-12-26
215 | 2029-12-26
216 | 2030-12-26
217 | 2031-12-26
218 | 2032-12-28
219 | 2033-12-26
220 | 2034-12-26
221 | 2035-12-26
222 | 2036-12-26
223 | 2037-12-28
224 | 2038-12-28
225 | 2039-12-26
226 | 2040-12-26
227 | 2041-12-26
228 | 2042-12-26
229 | 2043-12-28
230 | 2044-12-26
231 | 2045-12-26
232 | 2046-12-26
233 | 2047-12-26
234 | 2048-12-28
235 | 2049-12-28
236 |
237 |
238 |
239 |
240 |
241 |
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/ca.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Catalan (translation provided by q-quan)
10 | "SNOOZE_TIME" = "Temps d'Ajorn";
11 | "HOURS" = "hores";
12 | "MINUTES" = "minuts";
13 | "SECONDS" = "segons";
14 | "RESET_DEFAULT" = "Restaurar Predeterminat";
15 | "DEFAULT_SNOOZE_TIME" = "El temps d'ajorn predeterminat és de %@.";
16 | "SKIP" = "Ometre";
17 | "SKIP_TIME" = "Temps d’omissió";
18 | "SKIP_ALARM" = "Alarma d’omissió";
19 | "SKIP_QUESTION" = "T’agradaria saltar-te \"%@\", que està programat per les %@?";
20 | "SKIP_TIME_EXPLANATION" = "Tria a quant de temps se’t demanarà per ometre l’alarma abans de que soni.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/ch_holidays.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | dateCreated
6 | 2019-11-09T19:45:08Z
7 | holidays
8 |
9 |
10 | name
11 | Neujahrestag
12 | dates
13 |
14 | 2025-01-01
15 | 2026-01-01
16 | 2027-01-01
17 | 2028-01-01
18 | 2029-01-01
19 | 2030-01-01
20 | 2031-01-01
21 | 2032-01-01
22 | 2033-01-01
23 | 2034-01-01
24 | 2035-01-01
25 | 2036-01-01
26 | 2037-01-01
27 | 2038-01-01
28 | 2039-01-01
29 | 2040-01-01
30 | 2041-01-01
31 | 2042-01-01
32 | 2043-01-01
33 | 2044-01-01
34 | 2045-01-01
35 | 2046-01-01
36 | 2047-01-01
37 | 2048-01-01
38 | 2049-01-01
39 |
40 |
41 |
42 | name
43 | Karfreitag
44 | dates
45 |
46 | 2024-03-29
47 | 2025-04-18
48 | 2026-04-03
49 | 2027-03-26
50 | 2028-04-14
51 | 2029-03-30
52 | 2030-04-19
53 | 2031-04-11
54 | 2032-03-26
55 | 2033-04-15
56 | 2034-04-07
57 | 2035-03-23
58 | 2036-04-11
59 | 2037-04-03
60 | 2038-04-23
61 | 2039-04-08
62 | 2040-03-30
63 | 2041-04-19
64 | 2042-04-04
65 | 2043-03-27
66 | 2044-04-15
67 | 2045-04-07
68 | 2046-03-23
69 | 2047-04-12
70 | 2048-04-03
71 | 2049-04-16
72 |
73 |
74 |
75 | name
76 | Ostern
77 | dates
78 |
79 | 2024-03-31
80 | 2025-04-20
81 | 2026-04-05
82 | 2027-03-28
83 | 2028-04-16
84 | 2029-04-01
85 | 2030-04-21
86 | 2031-04-13
87 | 2032-03-28
88 | 2033-04-17
89 | 2034-04-09
90 | 2035-03-25
91 | 2036-04-13
92 | 2037-04-05
93 | 2038-04-25
94 | 2039-04-10
95 | 2040-04-01
96 | 2041-04-21
97 | 2042-04-06
98 | 2043-03-29
99 | 2044-04-17
100 | 2045-04-09
101 | 2046-03-25
102 | 2047-04-14
103 | 2048-04-05
104 | 2049-04-18
105 |
106 |
107 |
108 | name
109 | Ostermontag
110 | dates
111 |
112 | 2024-04-01
113 | 2025-04-21
114 | 2026-04-06
115 | 2027-03-29
116 | 2028-04-17
117 | 2029-04-02
118 | 2030-04-22
119 | 2031-04-14
120 | 2032-03-29
121 | 2033-04-18
122 | 2034-04-10
123 | 2035-03-26
124 | 2036-04-14
125 | 2037-04-06
126 | 2038-04-26
127 | 2039-04-11
128 | 2040-04-02
129 | 2041-04-22
130 | 2042-04-07
131 | 2043-03-30
132 | 2044-04-18
133 | 2045-04-10
134 | 2046-03-26
135 | 2047-04-15
136 | 2048-04-06
137 | 2049-04-19
138 |
139 |
140 |
141 | name
142 | Auffahrt
143 | dates
144 |
145 | 2024-05-09
146 | 2025-05-29
147 | 2026-05-14
148 | 2027-05-06
149 | 2028-05-25
150 | 2029-05-10
151 | 2030-05-30
152 | 2031-05-22
153 | 2032-05-06
154 | 2033-05-26
155 | 2034-05-18
156 | 2035-05-03
157 | 2036-05-22
158 | 2037-05-14
159 | 2038-06-03
160 | 2039-05-19
161 | 2040-05-10
162 | 2041-05-30
163 | 2042-05-15
164 | 2043-05-07
165 | 2044-05-26
166 | 2045-05-18
167 | 2046-05-03
168 | 2047-05-23
169 | 2048-05-14
170 | 2049-05-27
171 |
172 |
173 |
174 | name
175 | Pfingsten
176 | dates
177 |
178 | 2024-05-19
179 | 2025-06-08
180 | 2026-05-24
181 | 2027-05-16
182 | 2028-06-04
183 | 2029-05-20
184 | 2030-06-09
185 | 2031-06-01
186 | 2032-05-16
187 | 2033-06-05
188 | 2034-05-28
189 | 2035-05-13
190 | 2036-06-01
191 | 2037-05-24
192 | 2038-06-13
193 | 2039-05-29
194 | 2040-05-20
195 | 2041-06-09
196 | 2042-05-25
197 | 2043-05-17
198 | 2044-06-05
199 | 2045-05-28
200 | 2046-05-13
201 | 2047-06-02
202 | 2048-05-24
203 | 2049-06-06
204 |
205 |
206 |
207 | name
208 | Pfingstmontag
209 | dates
210 |
211 | 2024-05-20
212 | 2025-06-09
213 | 2026-05-25
214 | 2027-05-17
215 | 2028-06-05
216 | 2029-05-21
217 | 2030-06-10
218 | 2031-06-02
219 | 2032-05-17
220 | 2033-06-06
221 | 2034-05-29
222 | 2035-05-14
223 | 2036-06-02
224 | 2037-05-25
225 | 2038-06-14
226 | 2039-05-30
227 | 2040-05-21
228 | 2041-06-10
229 | 2042-05-26
230 | 2043-05-18
231 | 2044-06-06
232 | 2045-05-29
233 | 2046-05-14
234 | 2047-06-03
235 | 2048-05-25
236 | 2049-06-07
237 |
238 |
239 |
240 | name
241 | Nationalfeiertag
242 | dates
243 |
244 | 2024-08-01
245 | 2025-08-01
246 | 2026-08-01
247 | 2027-08-01
248 | 2028-08-01
249 | 2029-08-01
250 | 2030-08-01
251 | 2031-08-01
252 | 2032-08-01
253 | 2033-08-01
254 | 2034-08-01
255 | 2035-08-01
256 | 2036-08-01
257 | 2037-08-01
258 | 2038-08-01
259 | 2039-08-01
260 | 2040-08-01
261 | 2041-08-01
262 | 2042-08-01
263 | 2043-08-01
264 | 2044-08-01
265 | 2045-08-01
266 | 2046-08-01
267 | 2047-08-01
268 | 2048-08-01
269 | 2049-08-01
270 |
271 |
272 |
273 | name
274 | Weihnachten
275 | dates
276 |
277 | 2024-12-25
278 | 2025-12-25
279 | 2026-12-25
280 | 2027-12-25
281 | 2028-12-25
282 | 2029-12-25
283 | 2030-12-25
284 | 2031-12-25
285 | 2032-12-25
286 | 2033-12-25
287 | 2034-12-25
288 | 2035-12-25
289 | 2036-12-25
290 | 2037-12-25
291 | 2038-12-25
292 | 2039-12-25
293 | 2040-12-25
294 | 2041-12-25
295 | 2042-12-25
296 | 2043-12-25
297 | 2044-12-25
298 | 2045-12-25
299 | 2046-12-25
300 | 2047-12-25
301 | 2048-12-25
302 | 2049-12-25
303 |
304 |
305 |
306 |
307 |
308 |
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/checkmark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/layout/Library/Application Support/Sleeper.bundle/checkmark.png
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/checkmark@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/layout/Library/Application Support/Sleeper.bundle/checkmark@2x.png
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/checkmark@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/layout/Library/Application Support/Sleeper.bundle/checkmark@3x.png
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/cs.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Czech (translation provided by Sh4rPEYE)
10 | "SNOOZE_TIME" = "Délka odložení";
11 | "HOURS" = "hod";
12 | "MINUTES" = "min";
13 | "SECONDS" = "sek";
14 | "RESET_DEFAULT" = "Obnovit na výchozí";
15 | "DEFAULT_SNOOZE_TIME" = "Výchozí délka odložení je %@.";
16 | "SKIP" = "Přeskočit";
17 | "SKIP_TIME" = "Čas přeskočení";
18 | "SKIP_ALARM" = "Přeskočit budík";
19 | "SKIP_QUESTION" = "Chcete přeskočit budík \"%@\", který má zazvonit v %@?";
20 | "SKIP_TIME_EXPLANATION" = "Vyberte si počet nabídek k přeskočení budíku před tím, než zazvoní.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/da.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Danish (translation provided by Rasmushp and qlimax5000)
10 | "SNOOZE_TIME" = "Snooze interval";
11 | "HOURS" = "Timer";
12 | "MINUTES" = "Min.";
13 | "SECONDS" = "Sek.";
14 | "RESET_DEFAULT" = "Gendan standardindstillinger";
15 | "DEFAULT_SNOOZE_TIME" = "Standard snooze interval er %@.";
16 | "SKIP" = "Spring Over";
17 | "SKIP_TIME" = "Spring Time Over";
18 | "SKIP_ALARM" = "Spring Alarm Over";
19 | "SKIP_QUESTION" = "Vil du springe \"%@\" over? Den er sat til kl. \"%@\"";
20 | "SKIP_TIME_EXPLANATION" = "Vælg hvor lang tid før en alarm ringer at du vil spørges om du vil springe den fra.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/de.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // German (translation provided by thapublicMAN)
10 | "SNOOZE_TIME" = "Schlummerzeit";
11 | "HOURS" = "Std.";
12 | "MINUTES" = "Min.";
13 | "SECONDS" = "Sek.";
14 | "RESET_DEFAULT" = "Zurücksetzen";
15 | "DEFAULT_SNOOZE_TIME" = "Die Standard-Schlummerzeit ist %@.";
16 | "SKIP" = "Überspringen";
17 | "SKIP_TIME" = "Zeit-Überspringen";
18 | "SKIP_ALARM" = "Wecker-Überspringen";
19 | "SKIP_QUESTION" = "Möchtest du \"%@\" überspringen, der in %@ losgehen wird?";
20 | "SKIP_TIME_EXPLANATION" = "Wähle eine Zeitspanne in der du abgefragt wirst den Wecker zu überspringen, bevor er ausgelöst wird.";
21 |
22 | // German (translation provided by 100k_Jahresgehalt)
23 | "SKIP_DATES" = "Ausgelassene Tage";
24 | "SELECT_NEW_DATE" = "Wähle neues Datum";
25 | "SELECT_START_DATE" = "Wähle das Startdatum";
26 | "SELECT_END_DATE" = "Wähle das Enddatum";
27 | "EDIT_EXISTING_DATE" = "Vorhandenes Datum bearbeiten";
28 | "NUM_HOLIDAYS" = "%ld Feiertage";
29 | "NUM_HOLIDAY" = "%ld Feiertag";
30 | "NUM_DATES" = "%ld Tage";
31 | "NUM_DATE" = "%ld Tag";
32 | "DEFAULT_SKIP_DATES" = "Alle ausgelassene Tage für diesen Wecker entfernen.";
33 | "CONFIRM_DEFAULT_SKIP_DATES" = "Bist du sicher, dass du alle ausgelassene Tage für diesen Alarm entfernen möchtest?";
34 | "DEFAULT_SKIP_DATES_AND_HOLIDAYS" = "Alle ausgelassenen Tage, einschließlich aller Feiertagsauswahlen, für diesen Wecker entfernen.";
35 | "CONFIRM_DEFAULT_SKIP_DATES_AND_HOLIDAYS" = "Bist du sicher, dass du alle ausgelassenen Tage und Feiertagsauswahlen für diesen Wecker entfernen möchtest?";
36 | "SKIP_DATE_EXPLANATION" = "Dieser Wecker wird an den ausgewählten Tagen übersprungen.";
37 | "HOLIDAY_EXPLANATION" = "Wenn in diesem Land beobachtete Feiertage anerkannt werden und der Feiertag auf ein Wochenende fällt, wird das beobachtete Datum verwendet. Sobald ein Feiertag ausgewählt wurde, wird er auch weiterhin jedes Jahr übersprungen.";
38 | "ADD_NEW_DATE" = "Neues Datum hinzufügen...";
39 | "NUMBER_SELECTED" = "%ld Ausgewählt";
40 | "SKIP_REASON_POPUP" = "Du hast dich entschieden, diesen Wecker zu überspringen, wenn er das nächste Mal ausgelöst wird. Beim Speichern des Weckers wird diese Einstellung zurückgesetzt.";
41 | "SKIP_REASON_DATE" = "Das nächste Übersprungsdatum, das Sie für diesen Alarm ausgewählt haben, ist %@.";
42 | "SKIP_REASON_HOLIDAY" = "Der nächste Feiertag, den Sie für diesen Wecker ausgewählt haben, ist %@ (%@).";
43 | "ALL_HOLIDAYS" = "Alle Feiertage";
44 | "RECOMMENDED_HOLIDAYS_EXPLANATION" = "Diese Feiertage werden auf der Grundlage des aktuellen Standorts des Geräts empfohlen.";
45 | "SINGLE_DATE" = "Einzeldatum";
46 | "DATE_RANGE" = "Datumsbereich";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/el.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Greek (translation provided by TeamArrow)
10 | "SNOOZE_TIME" = "Ώρα υπνάκου";
11 | "HOURS" = "ώρες";
12 | "MINUTES" = "λεπτά";
13 | "SECONDS" = "δευτερόλεπτα";
14 | "RESET_DEFAULT" = "Επαναφορά στο κανονικό.";
15 | "DEFAULT_SNOOZE_TIME" = "Η κανονική ώρα \"υπνάκου\" είναι: %@.";
16 | "SKIP" = "Παράλειψη";
17 | "SKIP_TIME" = "Χρόνος παράλειψης";
18 | "SKIP_ALARM" = "Παράλειψη ξυπνητηριού";
19 | "SKIP_QUESTION" = "Θα θέλατε να παραλείψετε το οποίο είναι να χτυπήσει στις";
20 | "SKIP_TIME_EXPLANATION" = "Διαλέξτε ένα συγκεκριμένο χρόνο που θέλετε να παραλείψετε το ξυπνητήρι πριν χτυπήσει.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // English
10 | "SNOOZE_TIME" = "Snooze Time";
11 | "HOURS" = "hours";
12 | "MINUTES" = "min";
13 | "SECONDS" = "sec";
14 | "RESET_DEFAULT" = "Reset Default";
15 | "DEFAULT_SNOOZE_TIME" = "The default snooze time is %@.";
16 | "SKIP" = "Skip";
17 | "SKIP_TIME" = "Skip Time";
18 | "SKIP_ALARM" = "Skip Alarm";
19 | "SKIP_QUESTION" = "Would you like to skip \"%@\" which is scheduled to go off at %@?";
20 | "SKIP_TIME_EXPLANATION" = "Choose an amount of time that you will be prompted to skip the alarm before it fires.";
21 | "SKIP_DATES" = "Skip Dates";
22 | "SELECT_NEW_DATE" = "Select New Date";
23 | "SELECT_START_DATE" = "Select Start Date";
24 | "SELECT_END_DATE" = "Select End Date";
25 | "EDIT_EXISTING_DATE" = "Edit Existing Date";
26 | "NUM_HOLIDAYS" = "%ld Holidays";
27 | "NUM_HOLIDAY" = "%ld Holiday";
28 | "NUM_DATES" = "%ld Dates";
29 | "NUM_DATE" = "%ld Date";
30 | "DEFAULT_SKIP_DATES" = "Remove all skip dates for this alarm.";
31 | "CONFIRM_DEFAULT_SKIP_DATES" = "Are you sure you want to remove all of the skip dates for this alarm?";
32 | "DEFAULT_SKIP_DATES_AND_HOLIDAYS" = "Remove all skip dates, including any holiday selections, for this alarm.";
33 | "CONFIRM_DEFAULT_SKIP_DATES_AND_HOLIDAYS" = "Are you sure you want to remove all of the skip dates and holiday selections for this alarm?";
34 | "SKIP_DATE_EXPLANATION" = "This alarm will be skipped on the dates selected.";
35 | "HOLIDAY_EXPLANATION" = "If this country recognizes observed holidays and the holiday falls on a weekend, the observed date is used. Once a holiday is selected, it will continue to be skipped every year. The next date that will be skipped is displayed underneath each holiday name.";
36 | "ADD_NEW_DATE" = "Add New Date...";
37 | "NUMBER_SELECTED" = "%ld Selected";
38 | "SKIP_REASON_POPUP" = "You have decided to skip this alarm the next time it is set to fire. This decision will be reset if you save the alarm.";
39 | "SKIP_REASON_DATE" = "The next skip date you've selected for this alarm is %@.";
40 | "SKIP_REASON_HOLIDAY" = "The next holiday you've selected for this alarm is %@ (%@).";
41 | "ALL_HOLIDAYS" = "All Holidays";
42 | "RECOMMENDED_HOLIDAYS_EXPLANATION" = "These are the recommended holidays based on your device's current locale.";
43 | "SINGLE_DATE" = "Single Date";
44 | "DATE_RANGE" = "Date Range";
45 | "SKIP_EXPLANATION" = "Use the skip feature to temporarily disable alarms based on selected away dates/holidays or by setting a time in which the system will prompt you upon unlocking the device to skip the alarm before it fires.";
46 | "NO_FUTURE_DATES" = "No Future Dates Available";
47 | "AUTO_SET" = "Auto-Set";
48 | "AUTO_SET_DISABLED_EXPLANATION" = "The auto-set feature cannot be enabled on this device because the Weather application is not installed. Please install and configure the Weather application from the App Store and try again.";
49 | "AUTO_SET_WEATHER_EXPLANATION" = "The auto-set times will be determined by the first location set in the Weather application.\n\nIf the first location is determined using your device's location, then the Weather app will need to be opened any time the device is rebooted or SpringBoard is restarted to refresh the first location.\n\nTo ensure the auto-set feature is always functioning properly, please also set a secondary location manually in the Weather application.";
50 | "AUTO_SET_OPEN_WEATHER_APP" = "Open Weather App";
51 | "AUTO_SET_EXPLANATION" = "Choose an auto-set option to have this alarm automatically update its fire time.";
52 | "AUTO_SET_OFFSET_EXPLANATION" = "When enabled, the offset hours and minutes will be applied either before or after the selected auto-set time.\n\nFor example, if the sunrise auto-set option is selected with a 1-hour-before offset, the alarm will be set to fire 1 hour before the actual sunrise occurs.";
53 | "AUTO_SET_OFF_EXPLANATION" = "You can use the auto-set feature to have this alarm automatically set its time based on various parameters.";
54 | "AUTO_SET_ON_EXPLANATION" = "This alarm's fire time will automatically be set to %@.";
55 | "AUTO_SET_ON_WITH_OFFSET_EXPLANATION" = "This alarm's fire time will automatically be set to %@ %@ %@.";
56 | "BEFORE" = "Before";
57 | "AFTER" = "After";
58 | "OFFSET" = "Offset";
59 | "OFFSET_TIME" = "Offset Time";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/es.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Spanish (translation provided by Retosteante)
10 | "SNOOZE_TIME" = "Posponer Tiempo";
11 | "HOURS" = "horas";
12 | "MINUTES" = "min";
13 | "SECONDS" = "seg";
14 | "RESET_DEFAULT" = "Valores Predeterminados";
15 | "DEFAULT_SNOOZE_TIME" = "El tiempo predeterminado para posponer es %@.";
16 | "SKIP" = "Omitir";
17 | "SKIP_TIME" = "Omitir tiempo";
18 | "SKIP_ALARM" = "Omitir alarma";
19 | "SKIP_QUESTION" = "¿Deseas omitir la alarma \"%@\" que está programada para que suene a las %@?";
20 | "SKIP_TIME_EXPLANATION" = "Define el tiempo en el que se te pedirá omitir la alarma antes de que salte.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/fi.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 11/3/15.
6 |
7 | */
8 |
9 | // Finnish (translation provided by mikkoko)
10 | "SNOOZE_TIME" = "Torkkuaika";
11 | "HOURS" = "tuntia";
12 | "MINUTES" = "min";
13 | "SECONDS" = "sek";
14 | "RESET_DEFAULT" = "Palauta oletukset";
15 | "DEFAULT_SNOOZE_TIME" = "Oletus torkkuaika on %@.";
16 | "SKIP" = "Ohita";
17 | "SKIP_TIME" = "Ohita aika";
18 | "SKIP_ALARM" = "Ohita hälytys";
19 | "SKIP_QUESTION" = "Haluatko ohittaa herätyksen \"%@\" jonka on tarkoitus käynnistyä %@?";
20 | "SKIP_TIME_EXPLANATION" = "Aseta aika milloin sinua muistutetaan ohittamaan herätys ennen kuin se alkaa.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/fr.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // French (translation provided by Ziph0n & zazouboy)
10 | "SNOOZE_TIME" = "Temporisation";
11 | "HOURS" = "heures";
12 | "MINUTES" = "min";
13 | "SECONDS" = "sec";
14 | "RESET_DEFAULT" = "Réinitialiser";
15 | "DEFAULT_SNOOZE_TIME" = "La temporisation par défaut est %@.";
16 | "SKIP" = "Possibilité de l'ignorer";
17 | "SKIP_TIME" = "Durée";
18 | "SKIP_ALARM" = "Ignorer l'alarme";
19 | "SKIP_QUESTION" = "Voulez-vous ignorer \"%@\" qui doit se déclencher à %@?";
20 | "SKIP_TIME_EXPLANATION" = "Choisissez la durée pendant laquelle il vous sera demandé si vous souhaitez ignorer l'alarme avant qu'elle ne se déclenche.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/he.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Hebrew (translation provided by Aransh)
10 | "SNOOZE_TIME" = "זמן תנומה";
11 | "HOURS" = "שעות";
12 | "MINUTES" = "דקות";
13 | "SECONDS" = "שניות";
14 | "RESET_DEFAULT" = "אתחל לברירת מחדל";
15 | "DEFAULT_SNOOZE_TIME" = "זמן התנומה ברירת המחדל הוא %@.";
16 | "SKIP" = "דלג";
17 | "SKIP_TIME" = "זמן דילוג";
18 | "SKIP_ALARM" = "דלג/י על ההתראה";
19 | "SKIP_QUESTION" = "האם תרצה/י לדלג על ההתראה \"%@\" שמתוזמנת לפעול ב%@?";
20 | "SKIP_TIME_EXPLANATION" = "בחר כמות זמן שבו תישאל/י האם את/ה רוצה לדלג על ההתראה לפני שהיא מתחילה.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/hu.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 10/9/15.
6 |
7 | */
8 |
9 | // Hungarian (translation provided by benciikee)
10 | "SNOOZE_TIME" = "Szundi idő";
11 | "HOURS" = "Óra";
12 | "MINUTES" = "Perc";
13 | "SECONDS" = "Másodperc";
14 | "RESET_DEFAULT" = "Eredeti Beállítások";
15 | "DEFAULT_SNOOZE_TIME" = "Az alapértelmezett szundi idő %@";
16 | "SKIP" = "Kihagyás";
17 | "SKIP_TIME" = "Időpont kihagyása";
18 | "SKIP_ALARM" = "Ébresztő kihagyása";
19 | "SKIP_QUESTION" = "Biztosan ki szeretnéd hagyni a \"%@\" nevű ébresztőt ami %@ időben indul?";
20 | "SKIP_TIME_EXPLANATION" = "Válassz egy időintervallumot amikor a program megkér, hogy átugord az ébresztőt mielőtt az indul";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/layout/Library/Application Support/Sleeper.bundle/icon.png
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/id.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Indonesian (translation provided by flyinggreenfish)
10 | "SNOOZE_TIME" = "Waktu Tunda Alarm";
11 | "HOURS" = "Jam";
12 | "MINUTES" = "Menit";
13 | "SECONDS" = "Detik";
14 | "RESET_DEFAULT" = "Setelan Baku";
15 | "DEFAULT_SNOOZE_TIME" = "Setelan awal waktu tunda alarm adalah %@.";
16 | "SKIP" = "Lewati";
17 | "SKIP_TIME" = "Waktu yang dilewatkan";
18 | "SKIP_ALARM" = "Alarm yang dilewatkan";
19 | "SKIP_QUESTION" = "Apakah anda mau melewatkan \"%@\" yang dijadwalkan untuk %@?";
20 | "SKIP_TIME_EXPLANATION" = "Pilih waktu yang dibutuhkan untuk meminta anda melewatkan alarmnya sebelum alarmnya menyala.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/ind_holidays.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | dateCreated
6 | 2019-11-09T15:24:01Z
7 | holidays
8 |
9 |
10 | name
11 | New Year
12 | dates
13 |
14 | 2025-01-01
15 | 2026-01-01
16 | 2027-01-01
17 | 2028-01-01
18 | 2029-01-01
19 | 2030-01-01
20 | 2031-01-01
21 | 2032-01-01
22 | 2033-01-01
23 | 2034-01-01
24 | 2035-01-01
25 | 2036-01-01
26 | 2037-01-01
27 | 2038-01-01
28 | 2039-01-01
29 | 2040-01-01
30 | 2041-01-01
31 | 2042-01-01
32 | 2043-01-01
33 | 2044-01-01
34 | 2045-01-01
35 | 2046-01-01
36 | 2047-01-01
37 | 2048-01-01
38 | 2049-01-01
39 |
40 |
41 |
42 | name
43 | Makar Sankranti / Pongal
44 | dates
45 |
46 | 2025-01-14
47 | 2026-01-14
48 | 2027-01-14
49 | 2028-01-14
50 | 2029-01-14
51 | 2030-01-14
52 | 2031-01-14
53 | 2032-01-14
54 | 2033-01-14
55 | 2034-01-14
56 | 2035-01-14
57 | 2036-01-14
58 | 2037-01-14
59 | 2038-01-14
60 | 2039-01-14
61 | 2040-01-14
62 | 2041-01-14
63 | 2042-01-14
64 | 2043-01-14
65 | 2044-01-14
66 | 2045-01-14
67 | 2046-01-14
68 | 2047-01-14
69 | 2048-01-14
70 | 2049-01-14
71 |
72 |
73 |
74 | name
75 | Republic Day
76 | dates
77 |
78 | 2025-01-26
79 | 2026-01-26
80 | 2027-01-26
81 | 2028-01-26
82 | 2029-01-26
83 | 2030-01-26
84 | 2031-01-26
85 | 2032-01-26
86 | 2033-01-26
87 | 2034-01-26
88 | 2035-01-26
89 | 2036-01-26
90 | 2037-01-26
91 | 2038-01-26
92 | 2039-01-26
93 | 2040-01-26
94 | 2041-01-26
95 | 2042-01-26
96 | 2043-01-26
97 | 2044-01-26
98 | 2045-01-26
99 | 2046-01-26
100 | 2047-01-26
101 | 2048-01-26
102 | 2049-01-26
103 |
104 |
105 |
106 | name
107 | Labour Day
108 | dates
109 |
110 | 2024-05-01
111 | 2025-05-01
112 | 2026-05-01
113 | 2027-05-01
114 | 2028-05-01
115 | 2029-05-01
116 | 2030-05-01
117 | 2031-05-01
118 | 2032-05-01
119 | 2033-05-01
120 | 2034-05-01
121 | 2035-05-01
122 | 2036-05-01
123 | 2037-05-01
124 | 2038-05-01
125 | 2039-05-01
126 | 2040-05-01
127 | 2041-05-01
128 | 2042-05-01
129 | 2043-05-01
130 | 2044-05-01
131 | 2045-05-01
132 | 2046-05-01
133 | 2047-05-01
134 | 2048-05-01
135 | 2049-05-01
136 |
137 |
138 |
139 | name
140 | Independence Day
141 | dates
142 |
143 | 2024-08-15
144 | 2025-08-15
145 | 2026-08-15
146 | 2027-08-15
147 | 2028-08-15
148 | 2029-08-15
149 | 2030-08-15
150 | 2031-08-15
151 | 2032-08-15
152 | 2033-08-15
153 | 2034-08-15
154 | 2035-08-15
155 | 2036-08-15
156 | 2037-08-15
157 | 2038-08-15
158 | 2039-08-15
159 | 2040-08-15
160 | 2041-08-15
161 | 2042-08-15
162 | 2043-08-15
163 | 2044-08-15
164 | 2045-08-15
165 | 2046-08-15
166 | 2047-08-15
167 | 2048-08-15
168 | 2049-08-15
169 |
170 |
171 |
172 | name
173 | Gandhi Jayanti
174 | dates
175 |
176 | 2024-10-02
177 | 2025-10-02
178 | 2026-10-02
179 | 2027-10-02
180 | 2028-10-02
181 | 2029-10-02
182 | 2030-10-02
183 | 2031-10-02
184 | 2032-10-02
185 | 2033-10-02
186 | 2034-10-02
187 | 2035-10-02
188 | 2036-10-02
189 | 2037-10-02
190 | 2038-10-02
191 | 2039-10-02
192 | 2040-10-02
193 | 2041-10-02
194 | 2042-10-02
195 | 2043-10-02
196 | 2044-10-02
197 | 2045-10-02
198 | 2046-10-02
199 | 2047-10-02
200 | 2048-10-02
201 | 2049-10-02
202 |
203 |
204 |
205 | name
206 | Christmas
207 | dates
208 |
209 | 2024-12-25
210 | 2025-12-25
211 | 2026-12-25
212 | 2027-12-25
213 | 2028-12-25
214 | 2029-12-25
215 | 2030-12-25
216 | 2031-12-25
217 | 2032-12-25
218 | 2033-12-25
219 | 2034-12-25
220 | 2035-12-25
221 | 2036-12-25
222 | 2037-12-25
223 | 2038-12-25
224 | 2039-12-25
225 | 2040-12-25
226 | 2041-12-25
227 | 2042-12-25
228 | 2043-12-25
229 | 2044-12-25
230 | 2045-12-25
231 | 2046-12-25
232 | 2047-12-25
233 | 2048-12-25
234 | 2049-12-25
235 |
236 |
237 |
238 |
239 |
240 |
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/it.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Italian (translation provided by Agru007)
10 | "ADD_NEW_DATE" = "Aggiungi nuova data...";
11 | "ALL_HOLIDAYS" = "Tutte le festività";
12 | "CONFIRM_DEFAULT_SKIP_DATES" = "Sei sicuro di voler eliminare tutte le date in cui saltare questa sveglia?";
13 | "CONFIRM_DEFAULT_SKIP_DATES_AND_HOLIDAYS" = "Sei sicuro di voler eliminare tutte le date e le festività in cui saltare questa sveglia?";
14 | "DATE_RANGE" = "Intervallo di date";
15 | "DEFAULT_SKIP_DATES" = "Elimina tutte le date in cui saltare questa sveglia.";
16 | "DEFAULT_SKIP_DATES_AND_HOLIDAYS" = "Elimina tutte le date, incluse le festività, in cui saltare questa sveglia.";
17 | "DEFAULT_SNOOZE_TIME" = "Il ritardo predefinito è %@.";
18 | "EDIT_EXISTING_DATE" = "Modifica data esistente";
19 | "HOLIDAY_EXPLANATION" = "Se il paese scelto supporta il cambio di data per le festività che cadono nel weekend, Sleeper silenzierà la sveglia nel giorno feriale corrispondente. Quando viene scelta una festività, essa resta valida ogni anno.";
20 | "HOURS" = "ore";
21 | "MINUTES" = "min";
22 | "NUMBER_SELECTED" = "%ld selezionato";
23 | "NUM_DATE" = "%ld data";
24 | "NUM_DATES" = "%ld date";
25 | "NUM_HOLIDAY" = "%ld festività";
26 | "NUM_HOLIDAYS" = "%ld festività";
27 | "RECOMMENDED_HOLIDAYS_EXPLANATION" = "Queste sono le festività raccomandate in base alla località geografica impostata sul tuo telefono.";
28 | "RESET_DEFAULT" = "Ripristina valori predefiniti";
29 | "SECONDS" = "sec";
30 | "SELECT_END_DATE" = "Seleziona data finale";
31 | "SELECT_NEW_DATE" = "Seleziona nuova data";
32 | "SELECT_START_DATE" = "Seleziona data iniziale";
33 | "SINGLE_DATE" = "Singola data";
34 | "SKIP" = "Proponi salto";
35 | "SKIP_ALARM" = "Salta sveglia";
36 | "SKIP_DATES" = "Salta in data:";
37 | "SKIP_DATE_EXPLANATION" = "Questa sveglia verrà saltata nelle date selezionate";
38 | "SKIP_QUESTION" = "Vuoi saltare la sveglia \"%@\", programmata per le ore %@?";
39 | "SKIP_REASON_DATE" = "La prossima data in cui saltare questa sveglia è %@.";
40 | "SKIP_REASON_HOLIDAY" = "La prossima festività in cui saltare questa sveglia è %@ (%@).";
41 | "SKIP_REASON_POPUP" = "Hai scelto di saltare questa sveglia la prossima volta che scatterà. Questa scelta verrà dimenticata se salvi la sveglia.";
42 | "SKIP_TIME" = "Chiedi quando manca:";
43 | "SKIP_TIME_EXPLANATION" = "Scegli il lasso di tempo prima della sveglia in cui ti verrà proposto se saltarla.";
44 | "SNOOZE_TIME" = "Ritarda di:";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/ja.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Japanese (translation provided by koh_kun)
10 | "SNOOZE_TIME" = "スヌーズ間隔";
11 | "HOURS" = "時間";
12 | "MINUTES" = "分";
13 | "SECONDS" = "秒";
14 | "RESET_DEFAULT" = "初期設定に戻す";
15 | "DEFAULT_SNOOZE_TIME" = "スヌーズ間隔の初期設定は%@です。";
16 | "SKIP" = "スキップ";
17 | "SKIP_TIME" = "スキップ間隔";
18 | "SKIP_ALARM" = "アラームをスキップ";
19 | "SKIP_QUESTION" = "%@に設定されているアラーム「\"%@\"」をスキップしますか?";
20 | "SKIP_TIME_EXPLANATION" = "何度スキップされればアラームが発射される回数を決めてください。";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/ke_holidays.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | dateCreated
6 | 2019-11-09T15:58:27Z
7 | holidays
8 |
9 |
10 | name
11 | New Year's Day
12 | dates
13 |
14 | 2025-01-01
15 | 2026-01-01
16 | 2027-01-01
17 | 2028-01-01
18 | 2029-01-01
19 | 2030-01-01
20 | 2031-01-01
21 | 2032-01-01
22 | 2033-01-01
23 | 2034-01-02
24 | 2035-01-01
25 | 2036-01-01
26 | 2037-01-01
27 | 2038-01-01
28 | 2039-01-01
29 | 2040-01-02
30 | 2041-01-01
31 | 2042-01-01
32 | 2043-01-01
33 | 2044-01-01
34 | 2045-01-02
35 | 2046-01-01
36 | 2047-01-01
37 | 2048-01-01
38 | 2049-01-01
39 |
40 |
41 |
42 | name
43 | Good Friday
44 | dates
45 |
46 | 2024-03-29
47 | 2025-04-18
48 | 2026-04-03
49 | 2027-03-26
50 | 2028-04-14
51 | 2029-03-30
52 | 2030-04-19
53 | 2031-04-11
54 | 2032-03-26
55 | 2033-04-15
56 | 2034-04-07
57 | 2035-03-23
58 | 2036-04-11
59 | 2037-04-03
60 | 2038-04-23
61 | 2039-04-08
62 | 2040-03-30
63 | 2041-04-19
64 | 2042-04-04
65 | 2043-03-27
66 | 2044-04-15
67 | 2045-04-07
68 | 2046-03-23
69 | 2047-04-12
70 | 2048-04-03
71 | 2049-04-16
72 |
73 |
74 |
75 | name
76 | Easter Monday
77 | dates
78 |
79 | 2024-04-01
80 | 2025-04-21
81 | 2026-04-06
82 | 2027-03-29
83 | 2028-04-17
84 | 2029-04-02
85 | 2030-04-22
86 | 2031-04-14
87 | 2032-03-29
88 | 2033-04-18
89 | 2034-04-10
90 | 2035-03-26
91 | 2036-04-14
92 | 2037-04-06
93 | 2038-04-26
94 | 2039-04-11
95 | 2040-04-02
96 | 2041-04-22
97 | 2042-04-07
98 | 2043-03-30
99 | 2044-04-18
100 | 2045-04-10
101 | 2046-03-26
102 | 2047-04-15
103 | 2048-04-06
104 | 2049-04-19
105 |
106 |
107 |
108 | name
109 | Labour Day
110 | dates
111 |
112 | 2024-05-01
113 | 2025-05-01
114 | 2026-05-01
115 | 2027-05-01
116 | 2028-05-01
117 | 2029-05-01
118 | 2030-05-01
119 | 2031-05-01
120 | 2032-05-01
121 | 2033-05-02
122 | 2034-05-01
123 | 2035-05-01
124 | 2036-05-01
125 | 2037-05-01
126 | 2038-05-01
127 | 2039-05-02
128 | 2040-05-01
129 | 2041-05-01
130 | 2042-05-01
131 | 2043-05-01
132 | 2044-05-02
133 | 2045-05-01
134 | 2046-05-01
135 | 2047-05-01
136 | 2048-05-01
137 | 2049-05-01
138 |
139 |
140 |
141 | name
142 | Madaraka Day
143 | dates
144 |
145 | 2024-06-01
146 | 2025-06-02
147 | 2026-06-01
148 | 2027-06-01
149 | 2028-06-01
150 | 2029-06-01
151 | 2030-06-01
152 | 2031-06-02
153 | 2032-06-01
154 | 2033-06-01
155 | 2034-06-01
156 | 2035-06-01
157 | 2036-06-02
158 | 2037-06-01
159 | 2038-06-01
160 | 2039-06-01
161 | 2040-06-01
162 | 2041-06-01
163 | 2042-06-02
164 | 2043-06-01
165 | 2044-06-01
166 | 2045-06-01
167 | 2046-06-01
168 | 2047-06-01
169 | 2048-06-01
170 | 2049-06-01
171 |
172 |
173 |
174 | name
175 | Mashujaa Day
176 | dates
177 |
178 | 2024-10-21
179 | 2025-10-20
180 | 2026-10-20
181 | 2027-10-20
182 | 2028-10-20
183 | 2029-10-20
184 | 2030-10-21
185 | 2031-10-20
186 | 2032-10-20
187 | 2033-10-20
188 | 2034-10-20
189 | 2035-10-20
190 | 2036-10-20
191 | 2037-10-20
192 | 2038-10-20
193 | 2039-10-20
194 | 2040-10-20
195 | 2041-10-21
196 | 2042-10-20
197 | 2043-10-20
198 | 2044-10-20
199 | 2045-10-20
200 | 2046-10-20
201 | 2047-10-21
202 | 2048-10-20
203 | 2049-10-20
204 |
205 |
206 |
207 | name
208 | Jamhuri (Independence) Day
209 | dates
210 |
211 | 2024-12-12
212 | 2025-12-12
213 | 2026-12-12
214 | 2027-12-13
215 | 2028-12-12
216 | 2029-12-12
217 | 2030-12-12
218 | 2031-12-12
219 | 2032-12-13
220 | 2033-12-12
221 | 2034-12-12
222 | 2035-12-12
223 | 2036-12-12
224 | 2037-12-12
225 | 2038-12-13
226 | 2039-12-12
227 | 2040-12-12
228 | 2041-12-12
229 | 2042-12-12
230 | 2043-12-12
231 | 2044-12-12
232 | 2045-12-12
233 | 2046-12-12
234 | 2047-12-12
235 | 2048-12-12
236 | 2049-12-13
237 |
238 |
239 |
240 | name
241 | Christmas Day
242 | dates
243 |
244 | 2024-12-25
245 | 2025-12-25
246 | 2026-12-25
247 | 2027-12-25
248 | 2028-12-25
249 | 2029-12-25
250 | 2030-12-25
251 | 2031-12-25
252 | 2032-12-25
253 | 2033-12-26
254 | 2034-12-25
255 | 2035-12-25
256 | 2036-12-25
257 | 2037-12-25
258 | 2038-12-25
259 | 2039-12-26
260 | 2040-12-25
261 | 2041-12-25
262 | 2042-12-25
263 | 2043-12-25
264 | 2044-12-26
265 | 2045-12-25
266 | 2046-12-25
267 | 2047-12-25
268 | 2048-12-25
269 | 2049-12-25
270 |
271 |
272 |
273 | name
274 | Boxing Day
275 | dates
276 |
277 | 2024-12-26
278 | 2025-12-26
279 | 2026-12-26
280 | 2027-12-27
281 | 2028-12-26
282 | 2029-12-26
283 | 2030-12-26
284 | 2031-12-26
285 | 2032-12-27
286 | 2033-12-26
287 | 2034-12-26
288 | 2035-12-26
289 | 2036-12-26
290 | 2037-12-26
291 | 2038-12-27
292 | 2039-12-26
293 | 2040-12-26
294 | 2041-12-26
295 | 2042-12-26
296 | 2043-12-26
297 | 2044-12-26
298 | 2045-12-26
299 | 2046-12-26
300 | 2047-12-26
301 | 2048-12-26
302 | 2049-12-27
303 |
304 |
305 |
306 |
307 |
308 |
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/ko.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Korean (translation provided by mujjingun)
10 | "SNOOZE_TIME" = "스누즈 시간";
11 | "HOURS" = "시간";
12 | "MINUTES" = "분";
13 | "SECONDS" = "초";
14 | "RESET_DEFAULT" = "초기화";
15 | "DEFAULT_SNOOZE_TIME" = "기본 스누즈 시간은 %@ 입니다.";
16 | "SKIP" = "건너뛰기";
17 | "SKIP_TIME" = "건너뛸 시간";
18 | "SKIP_ALARM" = "알람 건너뛰기";
19 | "SKIP_QUESTION" = "%2$@에 울릴 알람 \"%1$@\"를 건너뛰시겠습니까?";
20 | "SKIP_TIME_EXPLANATION" = "알람이 울리기 직전에 나오는 알람 건너뛰기 옵션을 얼마동안 표시하시겠습니까?";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/la.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Latin (translation provided by swaggity_swiggity)
10 | "SNOOZE_TIME" = "quam diu expectare";
11 | "HOURS" = "horis";
12 | "MINUTES" = "minutus";
13 | "SECONDS" = "secundus";
14 | "RESET_DEFAULT" = "mutare ad regularem";
15 | "DEFAULT_SNOOZE_TIME" = "in defectu est, snooze tempus %@.";
16 | "SKIP" = "Autem";
17 | "SKIP_TIME" = "Degero";
18 | "SKIP_ALARM" = "Autem Clangor";
19 | "SKIP_QUESTION" = "Vis omit \"%@\" in qua venturus est %@ abire?";
20 | "SKIP_TIME_EXPLANATION" = "Elige quam promptus spatium antequam trepidatione ignes omit.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/ms.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Malay (translation provided by redzrex)
10 | "SNOOZE_TIME" = "Tunda Masa";
11 | "HOURS" = "jam";
12 | "MINUTES" = "min";
13 | "SECONDS" = "saat";
14 | "RESET_DEFAULT" = "Pulih Asal";
15 | "DEFAULT_SNOOZE_TIME" = "Masa tunda yang asal ialah %@.";
16 | "SKIP" = "Langkau";
17 | "SKIP_TIME" = "Langkau Masa";
18 | "SKIP_ALARM" = "Langkau Penggera";
19 | "SKIP_QUESTION" = "Adakah kamu ingin melangkau \"%@\" dimana ia telah dijadualkan untuk bunyi pada %@?";
20 | "SKIP_TIME_EXPLANATION" = "Pilih berapa kali kamu ingin didorong untuk melangkau penggera sebelum ia berbunyi.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/mx_holidays.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | dateCreated
6 | 2019-11-09T18:57:00Z
7 | holidays
8 |
9 |
10 | name
11 | Año Nuevo
12 | dates
13 |
14 | 2025-01-01
15 | 2026-01-01
16 | 2027-01-01
17 | 2027-12-31
18 | 2029-01-01
19 | 2030-01-01
20 | 2031-01-01
21 | 2032-01-01
22 | 2032-12-31
23 | 2034-01-02
24 | 2035-01-01
25 | 2036-01-01
26 | 2037-01-01
27 | 2038-01-01
28 | 2038-12-31
29 | 2040-01-02
30 | 2041-01-01
31 | 2042-01-01
32 | 2043-01-01
33 | 2044-01-01
34 | 2045-01-02
35 | 2046-01-01
36 | 2047-01-01
37 | 2048-01-01
38 | 2049-01-01
39 |
40 |
41 |
42 | name
43 | Día de la Constitución
44 | dates
45 |
46 | 2025-02-03
47 | 2026-02-02
48 | 2027-02-01
49 | 2028-02-07
50 | 2029-02-05
51 | 2030-02-04
52 | 2031-02-03
53 | 2032-02-02
54 | 2033-02-07
55 | 2034-02-06
56 | 2035-02-05
57 | 2036-02-04
58 | 2037-02-02
59 | 2038-02-01
60 | 2039-02-07
61 | 2040-02-06
62 | 2041-02-04
63 | 2042-02-03
64 | 2043-02-02
65 | 2044-02-01
66 | 2045-02-06
67 | 2046-02-05
68 | 2047-02-04
69 | 2048-02-03
70 | 2049-02-01
71 |
72 |
73 |
74 | name
75 | Natalicio de Benito Juárez
76 | dates
77 |
78 | 2024-03-18
79 | 2025-03-17
80 | 2026-03-16
81 | 2027-03-15
82 | 2028-03-20
83 | 2029-03-19
84 | 2030-03-18
85 | 2031-03-17
86 | 2032-03-15
87 | 2033-03-21
88 | 2034-03-20
89 | 2035-03-19
90 | 2036-03-17
91 | 2037-03-16
92 | 2038-03-15
93 | 2039-03-21
94 | 2040-03-19
95 | 2041-03-18
96 | 2042-03-17
97 | 2043-03-16
98 | 2044-03-21
99 | 2045-03-20
100 | 2046-03-19
101 | 2047-03-18
102 | 2048-03-16
103 | 2049-03-15
104 |
105 |
106 |
107 | name
108 | Día del Trabajo
109 | dates
110 |
111 | 2024-05-01
112 | 2025-05-01
113 | 2026-05-01
114 | 2027-05-01
115 | 2028-05-01
116 | 2029-05-01
117 | 2030-05-01
118 | 2031-05-01
119 | 2032-05-01
120 | 2033-05-01
121 | 2034-05-01
122 | 2035-05-01
123 | 2036-05-01
124 | 2037-05-01
125 | 2038-05-01
126 | 2039-05-01
127 | 2040-05-01
128 | 2041-05-01
129 | 2042-05-01
130 | 2043-05-01
131 | 2044-05-01
132 | 2045-05-01
133 | 2046-05-01
134 | 2047-05-01
135 | 2048-05-01
136 | 2049-05-01
137 |
138 |
139 |
140 | name
141 | Día de la Independencia
142 | dates
143 |
144 | 2024-09-16
145 | 2025-09-16
146 | 2026-09-16
147 | 2027-09-16
148 | 2028-09-15
149 | 2029-09-17
150 | 2030-09-16
151 | 2031-09-16
152 | 2032-09-16
153 | 2033-09-16
154 | 2034-09-15
155 | 2035-09-17
156 | 2036-09-16
157 | 2037-09-16
158 | 2038-09-16
159 | 2039-09-16
160 | 2040-09-17
161 | 2041-09-16
162 | 2042-09-16
163 | 2043-09-16
164 | 2044-09-16
165 | 2045-09-15
166 | 2046-09-17
167 | 2047-09-16
168 | 2048-09-16
169 | 2049-09-16
170 |
171 |
172 |
173 | name
174 | Día de la Revolución
175 | dates
176 |
177 | 2024-11-18
178 | 2025-11-17
179 | 2026-11-16
180 | 2027-11-15
181 | 2028-11-20
182 | 2029-11-19
183 | 2030-11-18
184 | 2031-11-17
185 | 2032-11-15
186 | 2033-11-21
187 | 2034-11-20
188 | 2035-11-19
189 | 2036-11-17
190 | 2037-11-16
191 | 2038-11-15
192 | 2039-11-21
193 | 2040-11-19
194 | 2041-11-18
195 | 2042-11-17
196 | 2043-11-16
197 | 2044-11-21
198 | 2045-11-20
199 | 2046-11-19
200 | 2047-11-18
201 | 2048-11-16
202 | 2049-11-15
203 |
204 |
205 |
206 | name
207 | Navidad
208 | dates
209 |
210 | 2024-12-25
211 | 2025-12-25
212 | 2026-12-25
213 | 2027-12-25
214 | 2028-12-25
215 | 2029-12-25
216 | 2030-12-25
217 | 2031-12-25
218 | 2032-12-25
219 | 2033-12-25
220 | 2034-12-25
221 | 2035-12-25
222 | 2036-12-25
223 | 2037-12-25
224 | 2038-12-25
225 | 2039-12-25
226 | 2040-12-25
227 | 2041-12-25
228 | 2042-12-25
229 | 2043-12-25
230 | 2044-12-25
231 | 2045-12-25
232 | 2046-12-25
233 | 2047-12-25
234 | 2048-12-25
235 | 2049-12-25
236 |
237 |
238 |
239 |
240 |
241 |
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/nb.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Norwegian (translation provided by BaTmAn9785 and switchpwn)
10 | "SNOOZE_TIME" = "Slumretid";
11 | "HOURS" = "timer";
12 | "MINUTES" = "min";
13 | "SECONDS" = "sek";
14 | "RESET_DEFAULT" = "Nullstill til standard";
15 | "DEFAULT_SNOOZE_TIME" = "Standard slumretid er %@.";
16 | "SKIP" = "Hopp over";
17 | "SKIP_TIME" = "Hopp over tid";
18 | "SKIP_ALARM" = "Hopp over alarm";
19 | "SKIP_QUESTION" = "Vil du hoppe over spørsmålet \"%@\" som er planlagt til å kjøre %@?";
20 | "SKIP_TIME_EXPLANATION" = "Velg tid som du vil bli spørt om å hoppe over før den kjører.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/ng_holidays.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | dateCreated
6 | 2020-06-19T14:53:28Z
7 | holidays
8 |
9 |
10 | name
11 | New Year's Day
12 | dates
13 |
14 | 2025-01-01
15 | 2026-01-01
16 | 2027-01-01
17 | 2028-01-01
18 | 2029-01-01
19 | 2030-01-01
20 | 2031-01-01
21 | 2032-01-01
22 | 2033-01-01
23 | 2034-01-01
24 | 2035-01-01
25 | 2036-01-01
26 | 2037-01-01
27 | 2038-01-01
28 | 2039-01-01
29 | 2040-01-01
30 | 2041-01-01
31 | 2042-01-01
32 | 2043-01-01
33 | 2044-01-01
34 | 2045-01-01
35 | 2046-01-01
36 | 2047-01-01
37 | 2048-01-01
38 | 2049-01-01
39 |
40 |
41 |
42 | name
43 | Worker's Day
44 | dates
45 |
46 | 2024-05-01
47 | 2025-05-01
48 | 2026-05-01
49 | 2027-05-01
50 | 2028-05-01
51 | 2029-05-01
52 | 2030-05-01
53 | 2031-05-01
54 | 2032-05-01
55 | 2033-05-01
56 | 2034-05-01
57 | 2035-05-01
58 | 2036-05-01
59 | 2037-05-01
60 | 2038-05-01
61 | 2039-05-01
62 | 2040-05-01
63 | 2041-05-01
64 | 2042-05-01
65 | 2043-05-01
66 | 2044-05-01
67 | 2045-05-01
68 | 2046-05-01
69 | 2047-05-01
70 | 2048-05-01
71 | 2049-05-01
72 |
73 |
74 |
75 | name
76 | Children's Day
77 | dates
78 |
79 | 2024-05-27
80 | 2025-05-27
81 | 2026-05-27
82 | 2027-05-27
83 | 2028-05-27
84 | 2029-05-27
85 | 2030-05-27
86 | 2031-05-27
87 | 2032-05-27
88 | 2033-05-27
89 | 2034-05-27
90 | 2035-05-27
91 | 2036-05-27
92 | 2037-05-27
93 | 2038-05-27
94 | 2039-05-27
95 | 2040-05-27
96 | 2041-05-27
97 | 2042-05-27
98 | 2043-05-27
99 | 2044-05-27
100 | 2045-05-27
101 | 2046-05-27
102 | 2047-05-27
103 | 2048-05-27
104 | 2049-05-27
105 |
106 |
107 |
108 | name
109 | Democracy Day
110 | dates
111 |
112 | 2024-06-12
113 | 2025-06-12
114 | 2026-06-12
115 | 2027-06-12
116 | 2028-06-12
117 | 2029-06-12
118 | 2030-06-12
119 | 2031-06-12
120 | 2032-06-12
121 | 2033-06-12
122 | 2034-06-12
123 | 2035-06-12
124 | 2036-06-12
125 | 2037-06-12
126 | 2038-06-12
127 | 2039-06-12
128 | 2040-06-12
129 | 2041-06-12
130 | 2042-06-12
131 | 2043-06-12
132 | 2044-06-12
133 | 2045-06-12
134 | 2046-06-12
135 | 2047-06-12
136 | 2048-06-12
137 | 2049-06-12
138 |
139 |
140 |
141 | name
142 | Independence Day
143 | dates
144 |
145 | 2024-10-01
146 | 2025-10-01
147 | 2026-10-01
148 | 2027-10-01
149 | 2028-10-01
150 | 2029-10-01
151 | 2030-10-01
152 | 2031-10-01
153 | 2032-10-01
154 | 2033-10-01
155 | 2034-10-01
156 | 2035-10-01
157 | 2036-10-01
158 | 2037-10-01
159 | 2038-10-01
160 | 2039-10-01
161 | 2040-10-01
162 | 2041-10-01
163 | 2042-10-01
164 | 2043-10-01
165 | 2044-10-01
166 | 2045-10-01
167 | 2046-10-01
168 | 2047-10-01
169 | 2048-10-01
170 | 2049-10-01
171 |
172 |
173 |
174 | name
175 | Christmas Day
176 | dates
177 |
178 | 2024-12-25
179 | 2025-12-25
180 | 2026-12-25
181 | 2027-12-25
182 | 2028-12-25
183 | 2029-12-25
184 | 2030-12-25
185 | 2031-12-25
186 | 2032-12-25
187 | 2033-12-25
188 | 2034-12-25
189 | 2035-12-25
190 | 2036-12-25
191 | 2037-12-25
192 | 2038-12-25
193 | 2039-12-25
194 | 2040-12-25
195 | 2041-12-25
196 | 2042-12-25
197 | 2043-12-25
198 | 2044-12-25
199 | 2045-12-25
200 | 2046-12-25
201 | 2047-12-25
202 | 2048-12-25
203 | 2049-12-25
204 |
205 |
206 |
207 | name
208 | Boxing Day
209 | dates
210 |
211 | 2024-12-26
212 | 2025-12-26
213 | 2026-12-26
214 | 2027-12-26
215 | 2028-12-26
216 | 2029-12-26
217 | 2030-12-26
218 | 2031-12-26
219 | 2032-12-26
220 | 2033-12-26
221 | 2034-12-26
222 | 2035-12-26
223 | 2036-12-26
224 | 2037-12-26
225 | 2038-12-26
226 | 2039-12-26
227 | 2040-12-26
228 | 2041-12-26
229 | 2042-12-26
230 | 2043-12-26
231 | 2044-12-26
232 | 2045-12-26
233 | 2046-12-26
234 | 2047-12-26
235 | 2048-12-26
236 | 2049-12-26
237 |
238 |
239 |
240 |
241 |
242 |
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/nl.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Dutch (translation provided by benjaminisdenaam)
10 | "SNOOZE_TIME" = "Snoozetijd";
11 | "HOURS" = "uren";
12 | "MINUTES" = "min";
13 | "SECONDS" = "sec";
14 | "RESET_DEFAULT" = "Herstel Standaardwaarden";
15 | "DEFAULT_SNOOZE_TIME" = "De standaard ingestelde snoozetijd is %@.";
16 | "SKIP" = "Overslaan";
17 | "SKIP_TIME" = "Tijd Overslaan";
18 | "SKIP_ALARM" = "Wekker Overslaan";
19 | "SKIP_QUESTION" = "Zou u graag \"%@\" overslaan, welke staat gepland om af te gaan binnen %@?";
20 | "SKIP_TIME_EXPLANATION" = "Hoeveel tijd voordat het alarm afgaat wilt u gevraagd worden om het alarm over te slaan?";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/open_in.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/layout/Library/Application Support/Sleeper.bundle/open_in.png
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/open_in@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/layout/Library/Application Support/Sleeper.bundle/open_in@2x.png
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/open_in@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joshuaseltzer/Sleeper/ee3bc5ff3c4ccf524594bff25d8f8019c903c289/layout/Library/Application Support/Sleeper.bundle/open_in@3x.png
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/pl.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Polish (translation provided by aaken)
10 | "SNOOZE_TIME" = "Czas drzemki";
11 | "HOURS" = "godz.";
12 | "MINUTES" = "min";
13 | "SECONDS" = "sek.";
14 | "RESET_DEFAULT" = "Przywróć ustawienia domyślne";
15 | "DEFAULT_SNOOZE_TIME" = "Standardowy czas drzemki to %@.";
16 | "SKIP" = "Pomiń";
17 | "SKIP_TIME" = "Czas pominięcia";
18 | "SKIP_ALARM" = "Pomiń alarm";
19 | "SKIP_QUESTION" = "Czy chciałbyś pominąć alarm \"%@\" który jest zaplanowany na %@?";
20 | "SKIP_TIME_EXPLANATION" = "Wybierz, po jakim czasie chcesz być zapytany o możliwość pominięcia alarmu, zanim zabrzmi.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/pt.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Portuguese (Brazil) (translation provided by mtlyoshi9)
10 | "SNOOZE_TIME" = "Tempo de soneca";
11 | "HOURS" = "horas";
12 | "MINUTES" = "min";
13 | "SECONDS" = "seg";
14 | "RESET_DEFAULT" = "Voltar ao padrão";
15 | "DEFAULT_SNOOZE_TIME" = "O tempo padrão de soneca é %@.";
16 | "SKIP" = "Pular";
17 | "SKIP_TIME" = "Tempo de adiamento";
18 | "SKIP_ALARM" = "Pular alarme";
19 | "SKIP_QUESTION" = "Você gostaria de pular \"%@\" que esta marcado para disparar as %@?";
20 | "SKIP_TIME_EXPLANATION" = "Escolhe um um período de tempo que você pode esperar antes que o alarme dispara.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/pt_PT.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Portuguese (Portugal) (translation provided by Ru1Sous4)
10 | "SNOOZE_TIME" = "Tempo de Snooze";
11 | "HOURS" = "horas";
12 | "MINUTES" = "min";
13 | "SECONDS" = "seg";
14 | "RESET_DEFAULT" = "Restaurar Valor Padrão";
15 | "DEFAULT_SNOOZE_TIME" = "O tempo padrão de snooze é %@.";
16 | "SKIP" = "Ignorar";
17 | "SKIP_TIME" = "Tempo para Ignorar";
18 | "SKIP_ALARM" = "Ignorar Alarme";
19 | "SKIP_QUESTION" = "Gostaria de ignorar o alarme \"%@\" que está marcado para as %@?";
20 | "SKIP_TIME_EXPLANATION" = "Escolha o período de tempo para poder ignorar o alarme antes de o mesmo tocar.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/ro.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Romanian (translation provided by blackdeath19)
10 | "SNOOZE_TIME" = "Timpul pentru ațipit";
11 | "HOURS" = "ore";
12 | "MINUTES" = "min";
13 | "SECONDS" = "seg";
14 | "RESET_DEFAULT" = "Resetează valorile implicite";
15 | "DEFAULT_SNOOZE_TIME" = "Timpul implicit pentru ațipit este %@.";
16 | "SKIP" = "Sari peste";
17 | "SKIP_TIME" = "Sari peste Timp";
18 | "SKIP_ALARM" = "Sari peste Alarmă";
19 | "SKIP_QUESTION" = "Ai vrea să sari peste \"%@\" care este programată să fie declanșată la %@?";
20 | "SKIP_TIME_EXPLANATION" = "Alege cu cât timp înainte să sune alarma dorești să fi anunțat pentru a sări peste ea.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/ru.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Russian (translation provided by aeternii & b3l1nsky)
10 | "SNOOZE_TIME" = "Период отложения";
11 | "HOURS" = "ч";
12 | "MINUTES" = "мин";
13 | "SECONDS" = "сек";
14 | "RESET_DEFAULT" = "Сброс настроек";
15 | "DEFAULT_SNOOZE_TIME" = "Стандартный период отложения – %@.";
16 | "SKIP" = "Отменяемый будильник";
17 | "SKIP_TIME" = "За сколько можно отменить";
18 | "SKIP_ALARM" = "Отменить будильник";
19 | "SKIP_QUESTION" = "Вы хотели бы отменить будильник \"%@\", который прозвенит в %@?";
20 | "SKIP_TIME_EXPLANATION" = "Выберите за сколько времени вам будет предложено отменить будильник, прежде чем он сработает";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/sg_holidays.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | dateCreated
6 | 2020-06-20T16:57:49Z
7 | holidays
8 |
9 |
10 | name
11 | New Year's Day
12 | dates
13 |
14 | 2025-01-01
15 | 2026-01-01
16 | 2027-01-01
17 | 2028-01-01
18 | 2029-01-01
19 | 2030-01-01
20 | 2031-01-01
21 | 2032-01-01
22 | 2033-01-01
23 | 2034-01-01
24 | 2035-01-01
25 | 2036-01-01
26 | 2037-01-01
27 | 2038-01-01
28 | 2039-01-01
29 | 2040-01-01
30 | 2041-01-01
31 | 2042-01-01
32 | 2043-01-01
33 | 2044-01-01
34 | 2045-01-01
35 | 2046-01-01
36 | 2047-01-01
37 | 2048-01-01
38 | 2049-01-01
39 |
40 |
41 |
42 | name
43 | Chinese New Year
44 | dates
45 |
46 | 2025-01-29
47 | 2025-01-30
48 | 2026-02-17
49 | 2026-02-18
50 | 2027-02-06
51 | 2027-02-07
52 | 2028-01-26
53 | 2028-01-27
54 | 2029-02-13
55 | 2029-02-14
56 | 2030-02-03
57 | 2030-02-04
58 | 2031-01-23
59 | 2031-01-24
60 | 2032-02-11
61 | 2032-02-12
62 | 2033-01-31
63 | 2033-02-01
64 | 2034-02-19
65 | 2034-02-20
66 | 2035-02-08
67 | 2035-02-09
68 | 2036-01-28
69 | 2036-01-29
70 | 2037-02-15
71 | 2037-02-16
72 | 2038-02-04
73 | 2038-02-05
74 | 2039-01-24
75 | 2039-01-25
76 | 2040-02-12
77 | 2040-02-13
78 | 2041-02-01
79 | 2041-02-02
80 | 2042-01-22
81 | 2042-01-23
82 | 2043-02-10
83 | 2043-02-11
84 | 2044-01-30
85 | 2044-01-31
86 | 2045-02-17
87 | 2045-02-18
88 | 2046-02-06
89 | 2046-02-07
90 | 2047-01-26
91 | 2047-01-27
92 | 2048-02-14
93 | 2048-02-15
94 | 2049-02-02
95 | 2049-02-03
96 |
97 |
98 |
99 | name
100 | Good Friday
101 | dates
102 |
103 | 2024-03-29
104 | 2025-04-18
105 | 2026-04-03
106 | 2027-03-26
107 | 2028-04-14
108 | 2029-03-30
109 | 2030-04-19
110 | 2031-04-11
111 | 2032-03-26
112 | 2033-04-15
113 | 2034-04-07
114 | 2035-03-23
115 | 2036-04-11
116 | 2037-04-03
117 | 2038-04-23
118 | 2039-04-08
119 | 2040-03-30
120 | 2041-04-19
121 | 2042-04-04
122 | 2043-03-27
123 | 2044-04-15
124 | 2045-04-07
125 | 2046-03-23
126 | 2047-04-12
127 | 2048-04-03
128 | 2049-04-16
129 |
130 |
131 |
132 | name
133 | Labour Day
134 | dates
135 |
136 | 2024-05-01
137 | 2025-05-01
138 | 2026-05-01
139 | 2027-05-01
140 | 2028-05-01
141 | 2029-05-01
142 | 2030-05-01
143 | 2031-05-01
144 | 2032-05-01
145 | 2033-05-01
146 | 2034-05-01
147 | 2035-05-01
148 | 2036-05-01
149 | 2037-05-01
150 | 2038-05-01
151 | 2039-05-01
152 | 2040-05-01
153 | 2041-05-01
154 | 2042-05-01
155 | 2043-05-01
156 | 2044-05-01
157 | 2045-05-01
158 | 2046-05-01
159 | 2047-05-01
160 | 2048-05-01
161 | 2049-05-01
162 |
163 |
164 |
165 | name
166 | National Day
167 | dates
168 |
169 | 2024-08-09
170 | 2025-08-09
171 | 2026-08-09
172 | 2027-08-09
173 | 2028-08-09
174 | 2029-08-09
175 | 2030-08-09
176 | 2031-08-09
177 | 2032-08-09
178 | 2033-08-09
179 | 2034-08-09
180 | 2035-08-09
181 | 2036-08-09
182 | 2037-08-09
183 | 2038-08-09
184 | 2039-08-09
185 | 2040-08-09
186 | 2041-08-09
187 | 2042-08-09
188 | 2043-08-09
189 | 2044-08-09
190 | 2045-08-09
191 | 2046-08-09
192 | 2047-08-09
193 | 2048-08-09
194 | 2049-08-09
195 |
196 |
197 |
198 | name
199 | Christmas Day
200 | dates
201 |
202 | 2024-12-25
203 | 2025-12-25
204 | 2026-12-25
205 | 2027-12-25
206 | 2028-12-25
207 | 2029-12-25
208 | 2030-12-25
209 | 2031-12-25
210 | 2032-12-25
211 | 2033-12-25
212 | 2034-12-25
213 | 2035-12-25
214 | 2036-12-25
215 | 2037-12-25
216 | 2038-12-25
217 | 2039-12-25
218 | 2040-12-25
219 | 2041-12-25
220 | 2042-12-25
221 | 2043-12-25
222 | 2044-12-25
223 | 2045-12-25
224 | 2046-12-25
225 | 2047-12-25
226 | 2048-12-25
227 | 2049-12-25
228 |
229 |
230 |
231 |
232 |
233 |
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/sv.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Swedish (translation provided by andreashenriksson)
10 | "SNOOZE_TIME" = "Snooze-längd";
11 | "HOURS" = "timmar";
12 | "MINUTES" = "min";
13 | "SECONDS" = "sek";
14 | "RESET_DEFAULT" = "Återställ till standard";
15 | "DEFAULT_SNOOZE_TIME" = "Standardtiden för snooze är %@.";
16 | "SKIP" = "Hoppa över";
17 | "SKIP_TIME" = "Hoppa över tid";
18 | "SKIP_ALARM" = "Hoppa över alarm";
19 | "SKIP_QUESTION" = "Vill du hoppa över \"%@\" som är planerat att gå igång vid %@?";
20 | "SKIP_TIME_EXPLANATION" = "Välj en viss tid innan alarmet går igång som du ska bli frågad att hoppa över alarmet.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/tr.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Turkish (translation provided by keremy)
10 | "SNOOZE_TIME" = "Erteleme Süresi";
11 | "HOURS" = "saat";
12 | "MINUTES" = "dakika";
13 | "SECONDS" = "saniye";
14 | "RESET_DEFAULT" = "Varsayılana Sıfırla";
15 | "DEFAULT_SNOOZE_TIME" = "Varsayılan erteleme saati %@.";
16 | "SKIP" = "Atla";
17 | "SKIP_TIME" = "Atlama süresi";
18 | "SKIP_ALARM" = "Alarmı atla";
19 | "SKIP_QUESTION" = "%@ saatinde çalacak \"%@\"ı atlamak ister misiniz?";
20 | "SKIP_TIME_EXPLANATION" = "Alarm çalmaya başlamadan alarmı atlayabileceğiniz bir süre seçin.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/vi.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Vietnamese (translation provided by tuancuongit)
10 | "SNOOZE_TIME" = "Thời gian hoãn";
11 | "HOURS" = "Giờ";
12 | "MINUTES" = "Phút";
13 | "SECONDS" = "Giây";
14 | "RESET_DEFAULT" = "Trả về mặc định";
15 | "DEFAULT_SNOOZE_TIME" = "Thời gian hoãn mặc định là %@.";
16 | "SKIP" = "Bỏ qua";
17 | "SKIP_TIME" = "Bỏ qua thời gian";
18 | "SKIP_ALARM" = "Bỏ qua báo thức";
19 | "SKIP_QUESTION" = "Bạn có muốn bỏ qua \"%@\", nó sẽ được tắt vào lúc %@";
20 | "SKIP_TIME_EXPLANATION" = "Chọn khoảng thời gian mà bạn muốn được báo trước khi nó hú.";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/zh_CN.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Simplified Chinese (translation provided by alanbchk)
10 | "SNOOZE_TIME" = "稍后提醒";
11 | "HOURS" = "时";
12 | "MINUTES" = "分";
13 | "SECONDS" = "秒";
14 | "RESET_DEFAULT" = "重置默认";
15 | "DEFAULT_SNOOZE_TIME" = "默认稍后提醒时间是 %@.";
16 | "SKIP" = "跳过";
17 | "SKIP_TIME" = "跳过时间";
18 | "SKIP_ALARM" = "跳过闹钟";
19 | "SKIP_QUESTION" = "预计启动%@?你是否想要跳过\"%@\"";
20 | "SKIP_TIME_EXPLANATION" = "选择你会被提示跳过闹钟激发之前的时间量";
--------------------------------------------------------------------------------
/layout/Library/Application Support/Sleeper.bundle/zh_TW.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 |
5 | Created by Joshua Seltzer on 1/21/15.
6 |
7 | */
8 |
9 | // Traditional Chinese (translation provided by alanbchk)
10 | "SNOOZE_TIME" = "稍後提醒";
11 | "HOURS" = "時";
12 | "MINUTES" = "分";
13 | "SECONDS" = "秒";
14 | "RESET_DEFAULT" = "重置默認";
15 | "DEFAULT_SNOOZE_TIME" = "默認稍後提醒時間是 %@.";
16 | "SKIP" = "跳過";
17 | "SKIP_TIME" = "跳過時間";
18 | "SKIP_ALARM" = "跳過鬧鐘";
19 | "SKIP_QUESTION" = "預計啟動%@?你是否想要跳過 \"%@\"";
20 | "SKIP_TIME_EXPLANATION" = "選擇你會被提示跳過鬧鐘激發之前的時間量";
--------------------------------------------------------------------------------
/localized_helper.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import sys
4 | import os
5 |
6 | # path to the Sleeper bundle which is used to store the holidays and localized strings
7 | SLEEPER_BUNDLE_PATH = "layout/Library/Application Support/Sleeper.bundle"
8 |
9 | # function that will remove x number of lines from the end of the localized string files (to remove the unnecessary holiday names)
10 | def remove_trailing_localized_strings(num_lines):
11 | # list all of the directories in the Sleeper bundle
12 | for (dirpath, dirnames, filenames) in os.walk(SLEEPER_BUNDLE_PATH):
13 | for dirname in dirnames:
14 | # each lproj directory should only contain one file, the localized strings file
15 | string_file_path = os.path.join(SLEEPER_BUNDLE_PATH, dirname, LOCALIZED_STRINGS_FILE)
16 | with open(string_file_path, 'r') as fp:
17 | existing_lines = fp.readlines()
18 | with open(string_file_path, 'w') as fp:
19 | fixed_lines = existing_lines[:-num_lines]
20 | fixed_lines[-1] = fixed_lines[-1].rstrip()
21 | fp.writelines(fixed_lines)
22 |
23 | if __name__== "__main__":
24 | if len(sys.argv) == 3:
25 | if sys.argv[1] == "-r":
26 | # update the localized string files to remove unused localization strings
27 | # e.g. this includes files from v5.0.0 and v5.0.1 (this code was used to fix the files in v6.0.0)
28 | remove_trailing_localized_strings(sys.argv[2])
29 | else:
30 | print("Incorrect usage!")
--------------------------------------------------------------------------------
/ui/SLMTABedtimeViewController.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLMTABedtimeViewController.x
3 | // The view controller that lets a user configure the sleep alarm (used in iOS 11 and iOS 12).
4 | //
5 | // Created by Joshua Seltzer on 4/1/18.
6 | //
7 | //
8 |
9 | #import "SLUserInterfaceHeaders.h"
10 | #import "../common/SLCommonHeaders.h"
11 | #import "../common/SLCompatibilityHelper.h"
12 |
13 | // interface for the sleep alarm (i.e. Bedtime) view controller
14 | @interface MTABedtimeViewController : UIViewController
15 |
16 | // the options view controller that is used to configure the Bedtime alarm (iOS 12)
17 | @property (retain, nonatomic) MTABedtimeOptionsViewController *optionsController;
18 |
19 | // the data source corresponding to the alarm (iOS 12)
20 | @property (retain, nonatomic) MTAlarmDataSource *dataSource;
21 |
22 | @end
23 |
24 | // custom interface for added properties and methods
25 | @interface MTABedtimeViewController (Sleeper)
26 |
27 | // reset the skip activation status for the sleep alarm when any preferences are changed
28 | - (void)SLResetSkipActivatedStatus;
29 |
30 | @end
31 |
32 | %group iOS12
33 |
34 | %hook MTABedtimeViewController
35 |
36 | - (void)showOptions:(UIBarButtonItem *)optionsBarButtonItem
37 | {
38 | // If the options controller does not have the Sleeper properties set, set them now (iOS 12). On iOS 11,
39 | // the preferences are set when the options view is loaded from the Alarm Manager.
40 | NSString *alarmId = [self.dataSource.sleepAlarm alarmIDString];
41 | SLAlarmPrefs *alarmPrefs = [SLPrefsManager alarmPrefsForAlarmId:alarmId];
42 | if (alarmPrefs == nil) {
43 | self.optionsController.SLAlarmPrefs = [[SLAlarmPrefs alloc] initWithAlarmId:alarmId];
44 | self.optionsController.SLAlarmPrefsChanged = YES;
45 | } else {
46 | self.optionsController.SLAlarmPrefs = alarmPrefs;
47 | self.optionsController.SLAlarmPrefsChanged = NO;
48 | }
49 | [self.optionsController updateDoneButtonEnabled];
50 |
51 | %orig;
52 | }
53 |
54 | %end
55 |
56 | %end // %group iOS12
57 |
58 | %group iOS11
59 |
60 | %hook MTABedtimeViewController
61 |
62 | // Method that will set the reset the skip activation status when various views are edited. This is not needed
63 | // on iOS 12 since the MTAlarmManager's updateAlarm will be called anytime the sleep timer is edited.
64 | %new
65 | - (void)SLResetSkipActivatedStatus
66 | {
67 | // get the alarm ID for the special sleep alarm
68 | AlarmManager *alarmManager = (AlarmManager *)[objc_getClass("AlarmManager") sharedManager];
69 | NSString *alarmId = [SLCompatibilityHelper alarmIdForAlarm:alarmManager.sleepAlarm];
70 |
71 | // check if we have alarm preferences for this alarm
72 | SLAlarmPrefs *alarmPrefs = [SLPrefsManager alarmPrefsForAlarmId:alarmId];
73 | if (alarmPrefs || alarmPrefs.skipActivationStatus != kSLSkipActivatedStatusUnknown) {
74 | // reset the skip activation status for this alarm
75 | [SLPrefsManager setSkipActivatedStatusForAlarmId:alarmId
76 | skipActivatedStatus:kSLSkipActivatedStatusUnknown];
77 | } else if (!alarmPrefs) {
78 | alarmPrefs = [[SLAlarmPrefs alloc] initWithAlarmId:alarmId];
79 | [SLPrefsManager saveAlarmPrefs:alarmPrefs];
80 | }
81 | }
82 |
83 | - (void)circleViewDidEndEditing:(id)sleepAlarmClockView
84 | {
85 | // reset the skip activation status
86 | [self SLResetSkipActivatedStatus];
87 |
88 | %orig;
89 | }
90 |
91 | - (void)enableSwitchToggled:(UISwitch *)enableSwitch
92 | {
93 | // reset the skip activation status
94 | [self SLResetSkipActivatedStatus];
95 |
96 | %orig;
97 | }
98 |
99 | %end
100 |
101 | %end // %group iOS11
102 |
103 | %ctor {
104 | // only initialize this file for particular versions
105 | if (kSLSystemVersioniOS12) {
106 | %init(iOS12)
107 | } else if (kSLSystemVersioniOS11) {
108 | %init(iOS11);
109 | }
110 | }
--------------------------------------------------------------------------------
/ui/SLMTASleepDetailViewController.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLMTASleepDetailViewController.x
3 | // The view controller which allows the user to change the sleep schedule for the bedtime alarm (iOS 13).
4 | //
5 | // Created by Joshua Seltzer on 11/22/19.
6 | //
7 | //
8 |
9 | #import "../common/SLCommonHeaders.h"
10 | #import "../common/SLAlarmPrefs.h"
11 | #import "../common/SLPrefsManager.h"
12 | #import "../common/SLCompatibilityHelper.h"
13 |
14 | // define an enum to reference the sections of the table view
15 | typedef enum SLSleepDetailViewControllerSection : NSUInteger {
16 | kSLSleepDetailViewControllerSectionScheduleToggle,
17 | kSLSleepDetailViewControllerSectionDaysOfWeekActive,
18 | kSLSleepDetailViewControllerNumSections
19 | } SLSleepDetailViewControllerSection;
20 |
21 | @interface MTASleepDetailViewController : UITableViewController
22 |
23 | // define the data source, which will include the sleep alarm
24 | @property (retain, nonatomic) MTAlarmDataSource *dataSource;
25 |
26 | @end
27 |
28 | // custom interface for added properties to the options controller
29 | @interface MTASleepDetailViewController (Sleeper)
30 |
31 | @property (nonatomic, retain) SLAlarmPrefs *SLAlarmPrefs;
32 |
33 | @end
34 |
35 | %hook MTASleepDetailViewController
36 |
37 | // the Sleeper preferences for the special sleep alarm
38 | %property (nonatomic, retain) SLAlarmPrefs *SLAlarmPrefs;
39 |
40 | - (void)viewDidLoad
41 | {
42 | // Load the preferences for the sleep alarm. The only reason we need the alarm preferences for this controller is to
43 | // potentially display the skip explanation string in the footer.
44 | NSString *alarmId = [self.dataSource.sleepAlarm alarmIDString];
45 | self.SLAlarmPrefs = [SLPrefsManager alarmPrefsForAlarmId:alarmId];
46 |
47 | %orig;
48 | }
49 |
50 | // Override with no implementation to prevent the footer string from being overridden.
51 | // As of iOS 13.2.2, this seems to be unused code / a bug since it is not shown unless we implement the
52 | // "titleForFooterInSection" delegate method.
53 | - (void)updateFooterWithSchedule:(NSInteger)schedule {}
54 |
55 | // potentially customize the footer text depending on whether or not the alarm is going to be skipped
56 | %new
57 | - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
58 | {
59 | NSString *footerTitle = nil;
60 | if (self.SLAlarmPrefs != nil && section == kSLSleepDetailViewControllerSectionScheduleToggle) {
61 | footerTitle = [self.SLAlarmPrefs skipReasonExplanation];
62 | }
63 | return footerTitle;
64 | }
65 |
66 | %end
67 |
68 | %ctor {
69 | if (kSLSystemVersioniOS13) {
70 | %init();
71 | }
72 | }
--------------------------------------------------------------------------------
/ui/SLMTSleepAlarmViewController.x:
--------------------------------------------------------------------------------
1 | //
2 | // SLMTSleepAlarmViewController.x
3 | // The view controller that lets a user configure the sleep alarm on iOS 10.
4 | //
5 | // Created by Joshua Seltzer on 2/26/17.
6 | //
7 | //
8 |
9 | #import "../common/SLCommonHeaders.h"
10 | #import "../common/SLAlarmPrefs.h"
11 | #import "../common/SLPrefsManager.h"
12 | #import "../common/SLCompatibilityHelper.h"
13 |
14 | // interface for the sleep alarm view controller
15 | @interface MTSleepAlarmViewController : UIViewController
16 |
17 | // reset the skip activation status for the sleep alarm when any preferences are changed
18 | - (void)SLResetSkipActivatedStatus;
19 |
20 | @end
21 |
22 | %hook MTSleepAlarmViewController
23 |
24 | %new
25 | - (void)SLResetSkipActivatedStatus
26 | {
27 | // get the alarm ID for the special sleep alarm
28 | AlarmManager *alarmManager = (AlarmManager *)[objc_getClass("AlarmManager") sharedManager];
29 | NSString *alarmId = [SLCompatibilityHelper alarmIdForAlarm:alarmManager.sleepAlarm];
30 |
31 | // check if we have alarm preferences for this alarm
32 | SLAlarmPrefs *alarmPrefs = [SLPrefsManager alarmPrefsForAlarmId:alarmId];
33 | if (alarmPrefs && alarmPrefs.skipActivationStatus != kSLSkipActivatedStatusUnknown) {
34 | // reset the skip activation status for this alarm
35 | [SLPrefsManager setSkipActivatedStatusForAlarmId:alarmId
36 | skipActivatedStatus:kSLSkipActivatedStatusUnknown];
37 | } else if (!alarmPrefs) {
38 | alarmPrefs = [[SLAlarmPrefs alloc] initWithAlarmId:alarmId];
39 | [SLPrefsManager saveAlarmPrefs:alarmPrefs];
40 | }
41 | }
42 |
43 | - (void)circleViewDidEndEditing:(id)sleepAlarmClockView
44 | {
45 | // reset the skip activation status
46 | [self SLResetSkipActivatedStatus];
47 |
48 | %orig;
49 | }
50 |
51 | - (void)enableSwitchToggled:(UISwitch *)enableSwitch
52 | {
53 | // reset the skip activation status
54 | [self SLResetSkipActivatedStatus];
55 |
56 | %orig;
57 | }
58 |
59 | %end
60 |
61 | %ctor {
62 | // only initialize this file if we are on iOS 10
63 | if (kSLSystemVersioniOS10) {
64 | %init();
65 | }
66 | }
--------------------------------------------------------------------------------
/ui/SLUserInterfaceHeaders.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLUserInterfaceHeaders.h
3 | // Contains all interfaces required for the User Interface project.
4 | //
5 | // Created by Joshua Seltzer on 2/15/20.
6 | //
7 | //
8 |
9 | #import "custom/SLSkipTimeViewController.h"
10 | #import "custom/SLSkipDatesViewController.h"
11 |
12 | // table view controller which configures the settings for the sleep alarm
13 | @interface MTABedtimeOptionsViewController : UITableViewController
14 |
15 | // updates the status of the done button on the view controller
16 | - (void)updateDoneButtonEnabled;
17 |
18 | @end
19 |
20 | // custom interface for added properties to the options controller
21 | @interface MTABedtimeOptionsViewController (Sleeper)
22 |
23 | @property (nonatomic, retain) SLAlarmPrefs *SLAlarmPrefs;
24 | @property (nonatomic, assign) BOOL SLAlarmPrefsChanged;
25 |
26 | @end
--------------------------------------------------------------------------------
/ui/custom/SLAutoSetOptionsTableViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLAutoSetOptionsTableViewController.h
3 | // Table view controller that presents the user with various options to configure the timer to automatically be set.
4 | //
5 | // Created by Joshua Seltzer on 7/1/20.
6 | // Copyright © 2020 Joshua Seltzer. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "SLEditDateTimeViewController.h"
11 | #import "../../common/SLPrefsManager.h"
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | // forward delcare the view controller class so that we can define it in the delegate
16 | @class SLAutoSetOptionsTableViewController;
17 |
18 | // delegate that will notify the object that holidays have been updated
19 | @protocol SLAutoSetOptionsDelegate
20 |
21 | // passes the updated auto-set selection and options to the delegate
22 | - (void)SLAutoSetOptionsTableViewController:(SLAutoSetOptionsTableViewController *)autoSetOptionsTableViewController
23 | didUpdateAutoSetOption:(SLAutoSetOption)autoSetOption
24 | withAutoSetOffsetOption:(SLAutoSetOffsetOption)autoSetOffsetOption
25 | withAutoSetOffsetHour:(NSInteger)autoSetOffsetHour
26 | withAutoSetOffsetMinute:(NSInteger)autoSetOffsetMinute;
27 |
28 | @end
29 |
30 | @interface SLAutoSetOptionsTableViewController : UITableViewController
31 |
32 | // initialize this controller with the selected auto-set settings
33 | - (instancetype)initWithAutoSetOption:(SLAutoSetOption)autoSetOption
34 | autoSetOffsetOption:(SLAutoSetOffsetOption)autoSetOffsetOption
35 | autoSetOffsetHour:(NSInteger)autoSetOffsetHour
36 | autoSetOffsetMinute:(NSInteger)autoSetOffsetMinute;
37 |
38 | // the delegate of this view controller
39 | @property (nonatomic, weak) id delegate;
40 |
41 | @end
42 |
43 | NS_ASSUME_NONNULL_END
44 |
--------------------------------------------------------------------------------
/ui/custom/SLEditDateTimeViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLEditDateTimeViewController.h
3 | //
4 | // Created by Joshua Seltzer on 1/3/19.
5 | // Copyright © 2019 Joshua Seltzer. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | // forward delcare the view controller class so that we can define it in the delegate
11 | @class SLEditDateTimeViewController;
12 |
13 | // define the height of the picker view
14 | #define kSLEditDateTimePickerViewHeight 216.0
15 |
16 | // delegate for this controller
17 | @protocol SLEditDateTimeViewControllerDelegate
18 |
19 | // all methods are optional since the delegate methods that are called will differ depending on which type of data is being edited
20 | @optional
21 |
22 | // notify the delegate that the date was saved
23 | - (void)SLEditDateTimeViewController:(SLEditDateTimeViewController *)editDateTimeViewController didSaveDate:(NSDate *)date;
24 |
25 | // notify the delegate that the hours/minutes were saved
26 | - (void)SLEditDateTimeViewController:(SLEditDateTimeViewController *)editDateTimeViewController didSaveHours:(NSInteger)hours andMinutes:(NSInteger)minutes;
27 |
28 | // notify the delegate that the selection was cancelled
29 | - (void)SLEditDateTimeViewControllerDidCancelSelection:(SLEditDateTimeViewController *)editDateTimeViewController;
30 |
31 | @end
32 |
33 | // customized view controller which simply contains a date or time picker view
34 | @interface SLEditDateTimeViewController : UIViewController
35 |
36 | // Initialize this controller with a required title and optional dates. Using this initilizer will put the picker in date mode.
37 | - (instancetype)initWithTitle:(NSString *)title initialDate:(NSDate *)initialDate minimumDate:(NSDate *)minimumDate maximumDate:(NSDate *)maximumDate;
38 |
39 | // Initialize this controller with a required title and optional hour/minutes. Using this initilizer will put the picker in countdown timer mode.
40 | - (instancetype)initWithTitle:(NSString *)title initialHours:(NSInteger)initialHours initialMinutes:(NSInteger)initialMinutes maximumHours:(NSInteger)maximumHours;
41 |
42 | // the delegate of this view controller
43 | @property (nonatomic, weak) id delegate;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/ui/custom/SLHolidaySelectionTableViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLHolidaySelectionTableViewController.h
3 | // Table view controller that allows the user to pick from a list of holidays.
4 | //
5 | // Created by Joshua Seltzer on 1/12/19.
6 | // Copyright © 2019 Joshua Seltzer. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "../../common/SLPrefsManager.h"
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | // forward delcare the view controller class so that we can define it in the delegate
15 | @class SLHolidaySelectionTableViewController;
16 |
17 | // delegate that will notify the object that holidays have been updated
18 | @protocol SLHolidaySelectionDelegate
19 |
20 | // passes the updated holiday selections for the holiday country
21 | - (void)SLHolidaySelectionTableViewController:(SLHolidaySelectionTableViewController *)holidaySelectionTableViewController
22 | didUpdateSelectedHolidays:(NSArray *)selectedHolidays
23 | forHolidayCountry:(SLHolidayCountry)holidayCountry;
24 |
25 | @end
26 |
27 | @interface SLHolidaySelectionTableViewController : UITableViewController
28 |
29 | // initialize this controller with the selected holidays and available holidays for a given holiday country
30 | - (instancetype)initWithSelectedHolidays:(NSArray *)selectedHolidays holidayResource:(NSDictionary *)holidayResource inHolidayCountry:(SLHolidayCountry)holidayCountry;
31 |
32 | // the delegate of this view controller
33 | @property (nonatomic, weak) id delegate;
34 |
35 | @end
36 |
37 | NS_ASSUME_NONNULL_END
38 |
--------------------------------------------------------------------------------
/ui/custom/SLPartialModalPresentationController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLPartialModalPresentationController.h
3 | //
4 | // Created by Joshua Seltzer on 1/3/19.
5 | // Copyright © 2019 Joshua Seltzer. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | // the custom presentation controller which is used to display a partial modal controller
11 | @interface SLPartialModalPresentationController : UIPresentationController
12 |
13 | // create a custom initialization to take in a percentage of how much to show the partial modal on
14 | // the screen and whether or not we can swipe to dismiss the presented controller
15 | - (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController
16 | presentingViewController:(UIViewController *)presentingViewController
17 | partialModalPercentage:(CGFloat)partialModalPercentage
18 | allowSwipeDismissal:(BOOL)allowSwipeDismissal;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/ui/custom/SLPartialModalPresentationController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SLPartialModalPresentationController.m
3 | //
4 | // Created by Joshua Seltzer on 1/3/19.
5 | // Copyright © 2019 Joshua Seltzer. All rights reserved.
6 | //
7 |
8 | #import "SLPartialModalPresentationController.h"
9 |
10 | @interface SLPartialModalPresentationController ()
11 |
12 | // the blurred view that will add blur to the presenting view controller background
13 | @property (nonatomic, strong) UIView *blurredView;
14 |
15 | // the percentage of the screen that should be displayed for this modal controller
16 | @property (nonatomic) CGFloat partialModalPercentage;
17 |
18 | // boolean which signifies whether or not we allow a swipe dismissal for the presented view controller
19 | @property (nonatomic) BOOL allowSwipeDismissal;
20 |
21 | @end
22 |
23 | @implementation SLPartialModalPresentationController
24 |
25 | // create a custom initialization to take in a percentage of how much to show the partial modal on
26 | // the screen
27 | - (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController
28 | presentingViewController:(UIViewController *)presentingViewController
29 | partialModalPercentage:(CGFloat)partialModalPercentage
30 | allowSwipeDismissal:(BOOL)allowSwipeDismissal
31 | {
32 | self = [super initWithPresentedViewController:presentedViewController
33 | presentingViewController:presentingViewController];
34 | if (self) {
35 | // set the partial modal percentage and swipe ability for this modal presentation
36 | self.partialModalPercentage = partialModalPercentage;
37 | self.allowSwipeDismissal = allowSwipeDismissal;
38 | }
39 | return self;
40 | }
41 |
42 | // override the getter for the blurred view
43 | - (UIView *)blurredView
44 | {
45 | // lazily load the blurred view once
46 | if (_blurredView == nil) {
47 | UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.containerView.bounds.size.width, self.containerView.bounds.size.height)];
48 |
49 | // create a blur affect on the view
50 | UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
51 | UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
52 | blurEffectView.frame = view.bounds;
53 | [view addSubview:blurEffectView];
54 |
55 | // add a swipe gesture to the blurred view to dismiss the presented view controller if enabled
56 | if (self.allowSwipeDismissal) {
57 | UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(blurredViewSwiped:)];
58 | swipeGesture.direction = UISwipeGestureRecognizerDirectionDown;
59 | [view addGestureRecognizer:swipeGesture];
60 | }
61 |
62 | _blurredView = view;
63 | }
64 |
65 | return _blurredView;
66 | }
67 |
68 | // invoked when the user swipes down on the blurred view
69 | - (void)blurredViewSwiped:(UITapGestureRecognizer *)tapGesture
70 | {
71 | // dismiss the presented view controller
72 | [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
73 | }
74 |
75 | - (CGRect)frameOfPresentedViewInContainerView
76 | {
77 | // create the frame for the view that will be presented based off of the modal percentage
78 | return CGRectMake(0.0,
79 | self.containerView.bounds.size.height * (1.0 - self.partialModalPercentage),
80 | self.containerView.bounds.size.width,
81 | self.containerView.bounds.size.height * self.partialModalPercentage);
82 | }
83 |
84 | - (void)presentationTransitionWillBegin
85 | {
86 | if (self.containerView != nil && self.presentingViewController.transitionCoordinator != nil) {
87 | // add the blurred view to the container view
88 | self.blurredView.alpha = 0.0;
89 | [self.containerView addSubview:self.blurredView];
90 | [self.blurredView addSubview:self.presentedViewController.view];
91 |
92 | // animate the alpha of the blurred view
93 | [self.presentingViewController.transitionCoordinator animateAlongsideTransition:^(id _Nonnull context) {
94 | self.blurredView.alpha = 1.0;
95 | }
96 | completion:nil];
97 | }
98 | }
99 |
100 | - (void)dismissalTransitionWillBegin
101 | {
102 | if (self.presentingViewController.transitionCoordinator != nil) {
103 | // animate the alpha of the blurred view
104 | [self.presentingViewController.transitionCoordinator animateAlongsideTransition:^(id _Nonnull context) {
105 | self.blurredView.alpha = 0.0;
106 | }
107 | completion:nil];
108 | }
109 | }
110 |
111 | - (void)dismissalTransitionDidEnd:(BOOL)completed
112 | {
113 | // once the transition is completed, destroy the blurred view that was created
114 | if (completed) {
115 | [self.blurredView removeFromSuperview];
116 | self.blurredView = nil;
117 | }
118 | }
119 |
120 | // override to disable showing in full screen for this presentation controller
121 | - (BOOL)shouldPresentInFullscreen
122 | {
123 | return NO;
124 | }
125 |
126 | @end
127 |
--------------------------------------------------------------------------------
/ui/custom/SLPickerTableViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLPickerTableViewController.h
3 | // Custom view controller with a time picker (hours, minutes, and seconds) on top with a table view on the bottom.
4 | //
5 | // Created by Joshua Seltzer on 9/24/15.
6 | // Copyright (c) 2015 Joshua Seltzer. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | // forward delcare the view controller class so that we can define it in the delegate
13 | @class SLPickerTableViewController;
14 |
15 | // delegate that will notify the object that the picker times have been updated
16 | @protocol SLPickerSelectionDelegate
17 |
18 | // passes the updated picker times to the delegate
19 | - (void)SLPickerTableViewController:(SLPickerTableViewController *)pickerTableViewController
20 | didUpdateWithHours:(NSInteger)hours
21 | minutes:(NSInteger)minutes
22 | seconds:(NSInteger)seconds;
23 |
24 | @end
25 |
26 | @interface SLPickerTableViewController : UIViewController
27 |
28 | // custom initialization method that sets the picker to the given times
29 | - (id)initWithHours:(NSInteger)hours
30 | minutes:(NSInteger)minutes
31 | seconds:(NSInteger)seconds;
32 |
33 | // move the time picker to the given hour, minute, and second values
34 | - (void)changePickerTimeWithHours:(NSInteger)hours
35 | minutes:(NSInteger)minutes
36 | seconds:(NSInteger)seconds
37 | animated:(BOOL)animated;
38 |
39 | // the options table which will take up the rest of the view
40 | @property (nonatomic, strong) UITableView *optionsTableView;
41 |
42 | // the delegate of this view controller
43 | @property (nonatomic, weak) id delegate;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/ui/custom/SLSkipDatesViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLSkipDatesViewController.h
3 | //
4 | // Created by Joshua Seltzer on 1/2/19.
5 | // Copyright © 2019 Joshua Seltzer. All rights reserved.
6 | //
7 |
8 | #import
9 | #import "SLEditDateTimeViewController.h"
10 | #import "SLHolidaySelectionTableViewController.h"
11 | #import "../../common/SLAlarmPrefs.h"
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | // forward delcare the view controller class so that we can define it in the delegate
16 | @class SLSkipDatesViewController;
17 |
18 | // delegate that will notify the object that skip dates have been updated
19 | @protocol SLSkipDatesDelegate
20 |
21 | // passes the updated picker times to the delegate
22 | - (void)SLSkipDatesViewController:(SLSkipDatesViewController *)skipDatesViewController
23 | didUpdateCustomSkipDates:(NSArray *)customSkipDates
24 | holidaySkipDates:(NSDictionary *)holidaySkipDates;
25 |
26 | @end
27 |
28 | @interface SLSkipDatesViewController : UITableViewController
29 |
30 | // initialize this controller with the preferences for the given alarm
31 | - (instancetype)initWithAlarmPrefs:(SLAlarmPrefs *)alarmPrefs;
32 |
33 | // the delegate of this view controller
34 | @property (nonatomic, weak) id delegate;
35 |
36 | @end
37 |
38 | NS_ASSUME_NONNULL_END
39 |
--------------------------------------------------------------------------------
/ui/custom/SLSkipTimeViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLSkipTimeViewController.h
3 | // Customized picker table view controller for selecting the skip time.
4 | //
5 | // Created by Joshua Seltzer on 7/19/15.
6 | // Copyright (c) 2015 Joshua Seltzer. All rights reserved.
7 | //
8 |
9 | #import "SLPickerTableViewController.h"
10 |
11 | @interface SLSkipTimeViewController : SLPickerTableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ui/custom/SLSkipTimeViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SLSkipTimeViewController.m
3 | // Customized picker table view controller for selecting the skip time.
4 | //
5 | // Created by Joshua Seltzer on 7/19/15.
6 | // Copyright (c) 2015 Joshua Seltzer. All rights reserved.
7 | //
8 |
9 | #import "SLSkipTimeViewController.h"
10 | #import "../../common/SLLocalizedStrings.h"
11 |
12 | @implementation SLSkipTimeViewController
13 |
14 | // override to customize the view upon load
15 | - (void)viewDidLoad
16 | {
17 | [super viewDidLoad];
18 |
19 | // set the title of the view controller
20 | self.title = kSLSkipTimeString;
21 | self.optionsTableView.scrollEnabled = NO;
22 | }
23 |
24 | #pragma mark - UITableViewDataSource
25 |
26 | // returns the number of sections for a table view
27 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
28 | {
29 | // return a single section so that we can display a footer message in the table
30 | return 1;
31 | }
32 |
33 | // returns the number of rows for a table view
34 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
35 | {
36 | // there are no rows for this table
37 | return 0;
38 | }
39 |
40 | // returns a cell for a table at an index path
41 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
42 | {
43 | // Since we are not creating any cells, this function will never get called. Therefore we are
44 | // safe returning nil here.
45 | return nil;
46 | }
47 |
48 | // return a footer view for each table view section
49 | - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
50 | {
51 | return kSLSkipTimeExplanationString;
52 | }
53 |
54 | #pragma mark - UITableViewDelegate
55 |
56 | // return to include some space between the time picker view and the message we will display in the
57 | // footer
58 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
59 | {
60 | return 5.0f;
61 | }
62 |
63 | @end
64 |
--------------------------------------------------------------------------------
/ui/custom/SLSnoozeTimeViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SLSnoozeTimeViewController.h
3 | // Customized picker table view controller for selecting the snooze time.
4 | //
5 | // Created by Joshua Seltzer on 10/12/14.
6 | // Copyright (c) 2014 Joshua Seltzer. All rights reserved.
7 | //
8 |
9 | #import "SLPickerTableViewController.h"
10 |
11 | @interface SLSnoozeTimeViewController : SLPickerTableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ui/custom/SLSnoozeTimeViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SLSnoozeTimeViewController.m
3 | // Customized picker table view controller for selecting the snooze time.
4 | //
5 | // Created by Joshua Seltzer on 10/12/14.
6 | // Copyright (c) 2014 Joshua Seltzer. All rights reserved.
7 | //
8 |
9 | #import "SLSnoozeTimeViewController.h"
10 | #import "../../common/SLPrefsManager.h"
11 | #import "../../common/SLLocalizedStrings.h"
12 | #import "../../common/SLCompatibilityHelper.h"
13 |
14 | @implementation SLSnoozeTimeViewController
15 |
16 | // override to customize the view upon load
17 | - (void)viewDidLoad
18 | {
19 | [super viewDidLoad];
20 |
21 | // set the title of the view controller
22 | self.title = kSLSnoozeTimeString;
23 | }
24 |
25 | #pragma mark - UITableViewDataSource
26 |
27 | // returns the number of sections for a table view
28 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
29 | {
30 | return 1;
31 | }
32 |
33 | // returns the number of rows for a table view
34 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
35 | {
36 | return 1;
37 | }
38 |
39 | // returns a cell for a table at an index path
40 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
41 | {
42 | // create an identifier for our table view cell
43 | static NSString *const optionTableButtonCellIdentifier = @"optionTableButtonCellIdentifier";
44 |
45 | // attempt to dequeue the cell from the table
46 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:optionTableButtonCellIdentifier];
47 |
48 | // if the cell doesn't exist yet, create a new one
49 | if (!cell) {
50 | // create a new default cell
51 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
52 | reuseIdentifier:optionTableButtonCellIdentifier];
53 |
54 | // on newer versions of iOS, we need to set the background views for the cell
55 | if (kSLSystemVersioniOS14 || kSLSystemVersioniOS13) {
56 | cell.backgroundColor = [SLCompatibilityHelper tableViewCellBackgroundColor];
57 | }
58 |
59 | // set the background color of the cell to clear to remove the selection color
60 | if (@available(iOS 10.0, *)) {
61 | UIView *backgroundView = [[UIView alloc] init];
62 | backgroundView.backgroundColor = [SLCompatibilityHelper tableViewCellSelectedBackgroundColor];
63 | cell.selectedBackgroundView = backgroundView;
64 | }
65 | }
66 |
67 | // customize the cell
68 | cell.textLabel.text = kSLResetDefaultString;
69 | cell.textLabel.textAlignment = NSTextAlignmentCenter;
70 |
71 | // set the color of the button to the red, destructive color as defined by Apple in other cells
72 | cell.textLabel.textColor = [SLCompatibilityHelper destructiveLabelColor];
73 |
74 | return cell;
75 | }
76 |
77 | // return a footer view for each table view section
78 | - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
79 | {
80 | // We only have one section which defines the default snooze button. Display a message indicating
81 | // to the user what the default snooze time is
82 | NSString *defaultSnoozeTime = [NSString stringWithFormat:@"%02ld:%02ld:%02ld", (long)kSLDefaultSnoozeHour,
83 | (long)kSLDefaultSnoozeMinute, (long)kSLDefaultSnoozeSecond];
84 | return kSLDefaultSnoozeTimeString(defaultSnoozeTime);
85 | }
86 |
87 | #pragma mark - UITableViewDelegate
88 |
89 | // handle table view cell selection
90 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
91 | {
92 | // for now, we only have one button so we can assume it is the one that resets the default snooze
93 | // picker values
94 | [self changePickerTimeWithHours:kSLDefaultSnoozeHour
95 | minutes:kSLDefaultSnoozeMinute
96 | seconds:kSLDefaultSnoozeSecond
97 | animated:YES];
98 |
99 | // deselect the row with animation
100 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
101 | }
102 |
103 | @end
104 |
--------------------------------------------------------------------------------