mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-17 23:18:27 +02:00
Feature/1801 ruhezeit einstellungsmenu
This commit is contained in:
@@ -468,9 +468,6 @@ final class BuildSettings: NSObject {
|
||||
// MARK: Room Member Details Screen (bwi=true)
|
||||
static let roomMemberDetailsHideLeaveButton : Bool = true
|
||||
|
||||
// MARK: Rest time feature (bwi=false)
|
||||
static let featureWorkTime : Bool = false
|
||||
|
||||
// MARK: Room create options (bwi=false)
|
||||
static let enableShowInRoomDirectory : Bool = false
|
||||
|
||||
|
||||
@@ -242,4 +242,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: 82644f3408b6874a1dcd71e332ed7b8d18cac2f5
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
COCOAPODS: 1.10.1
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
buildImplicitDependencies = "YES"
|
||||
runPostActionsOnFailure = "NO">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
|
||||
@@ -38,6 +38,33 @@
|
||||
|
||||
"bwi_mdm_logout_message" = "Die Konfiguration hat sich geändert. Bitte melde dich neu an.";
|
||||
|
||||
// MARK - Notification Times bwi
|
||||
"bwi_notification_times_monday" = "Montag";
|
||||
"bwi_notification_times_tuesday" = "Dienstag";
|
||||
"bwi_notification_times_wednesday" = "Mittwoch";
|
||||
"bwi_notification_times_thursday" = "Donnerstag";
|
||||
"bwi_notification_times_friday" = "Freitag";
|
||||
"bwi_notification_times_saturday" = "Samstag";
|
||||
"bwi_notification_times_sunday" = "Sonntag";
|
||||
"bwi_notification_times_monday_short" = "Mo";
|
||||
"bwi_notification_times_tuesday_short" = "Di";
|
||||
"bwi_notification_times_wednesday_short" = "Mi";
|
||||
"bwi_notification_times_thursday_short" = "Do";
|
||||
"bwi_notification_times_friday_short" = "Fr";
|
||||
"bwi_notification_times_saturday_short" = "Sa";
|
||||
"bwi_notification_times_sunday_short" = "So";
|
||||
|
||||
"bwi_notification_times" = "Benachrichtigungszeiten";
|
||||
"bwi_notification_times_done_action" = "Fertig";
|
||||
"bwi_notification_times_toggle_title" = "Benachrichtigungszeiten";
|
||||
"bwi_notification_times_toggle_description" = "Außerhalb der eingestellten Benachrichtigungszeiten erhälst du keine Benachrichtigungen. Diese Regel kannst du pro Raum und Chat ein- und ausschalten.";
|
||||
"bwi_notification_times_start_time" = "von";
|
||||
"bwi_notification_times_end_time" = "bis";
|
||||
"bwi_notification_times_button_activate" = "Am %@ benachrichtigen";
|
||||
"bwi_notification_times_button_deactivate" = "Am %@ nicht benachrichtigen";
|
||||
"bwi_notification_times_status_activated" = "Am %@ bekommst du Benachrichtigungen";
|
||||
"bwi_notification_times_status_deactivated" = "Am %@ bekommst du keine Benachrichtigungen";
|
||||
|
||||
"bwi_room_member_details_userlabel" = "Funktion in %@: %@";
|
||||
"bwi_room_member_section_userlabels" = "Funktion in %@";
|
||||
"bwi_room_member_userlabels_description" = "Als Administrator kannst du für Personen im Raum eine Funktion hinzufügen und entfernen.\nDiese ist für alle Raummitglieder sichtbar.";
|
||||
|
||||
@@ -1449,15 +1449,8 @@
|
||||
"room_message_replying_to" = "%@ anworten";
|
||||
"room_message_editing" = "Bearbeitung";
|
||||
|
||||
// MARK - Rest Time bwi
|
||||
"settings_enable_rest_time" = "Ruhezeitregelung";
|
||||
"room_details_main_section_rest_time" = "Ruhezeitregelung";
|
||||
"room_details_main_section_rest_time_global_disabled" = "Aktiviere die Ruhezeitregelung in den Profileinstellungen";
|
||||
"room_details_main_section_rest_time_global" = "";
|
||||
"room_details_main_section_rest_time_locally_enabled" = "";
|
||||
"room_details_main_section_rest_time_locally_disabled" = "Nicht aktiv";
|
||||
"room_details_main_section_rest_time_restday" = "heute Ruhetag";
|
||||
"room_details_main_section_rest_time_time" = "%@ - %@";
|
||||
// MARK - Notification Times bwi
|
||||
"settings_enable_notification_times" = "Benachrichtigungszeiten";
|
||||
|
||||
"space_beta_announce_information" = "Spaces bieten neue Möglichkeiten um Räume und Personen zu gruppieren. Sie sind noch nicht auf iOS verfügbar, aber du kannst sie jetzt schon mit Web und Desktop nutzen.";
|
||||
"space_feature_unavailable_information" = "Spaces bieten neue Möglichkeiten um Räume und Personen zu gruppieren.\n\nBald werden sie auch hier verfügbar sein. Für den Moment kannst du ihnen auf einer der anderen Plattformen beitreten und hier auf alle Räume zugreifen, denen du dort beitrittst.";
|
||||
|
||||
@@ -38,6 +38,31 @@
|
||||
|
||||
"bwi_mdm_logout_message" = "The configuration has changed. Please reconnect.";
|
||||
|
||||
// MARK - Notification Times bwi
|
||||
"bwi_notification_times_monday" = "Monday";
|
||||
"bwi_notification_times_tuesday" = "Tuesday";
|
||||
"bwi_notification_times_wednesday" = "Wednesday";
|
||||
"bwi_notification_times_thursday" = "Thursday";
|
||||
"bwi_notification_times_friday" = "Friday";
|
||||
"bwi_notification_times_saturday" = "Saturday";
|
||||
"bwi_notification_times_sunday" = "Sunday";
|
||||
"bwi_notification_times_monday_short" = "Mo";
|
||||
"bwi_notification_times_tuesday_short" = "Tu";
|
||||
"bwi_notification_times_wednesday_short" = "We";
|
||||
"bwi_notification_times_thursday_short" = "Th";
|
||||
"bwi_notification_times_friday_short" = "Fr";
|
||||
"bwi_notification_times_saturday_short" = "Sa";
|
||||
"bwi_notification_times_sunday_short" = "Su";
|
||||
|
||||
"bwi_notification_times" = "Notification Times";
|
||||
"bwi_notification_times_done_action" = "Done";
|
||||
"bwi_notification_times_toggle_title" = "Notification Times";
|
||||
"bwi_notification_times_toggle_description" = "You will not receive notifications outside the set notification times. You can switch this rule on and off per room and chat.";
|
||||
"bwi_notification_times_start_time" = "from";
|
||||
"bwi_notification_times_end_time" = "till";
|
||||
"bwi_notification_times_button_activate" = "Activate notifications on %@";
|
||||
"bwi_notification_times_button_deactivate" = "Deactivate notifications on %@";
|
||||
|
||||
"bwi_room_member_details_userlabel" = "Function in %@: %@";
|
||||
"bwi_room_member_section_userlabels" = "Function in %@";
|
||||
"bwi_room_member_userlabels_description" = "As an admin, you can add and remove a function label for a room member. This function label is visible to all room members.";
|
||||
|
||||
@@ -1942,15 +1942,8 @@ Tap the + to start adding people.";
|
||||
"space_beta_announce_subtitle" = "The new version of communities";
|
||||
"space_beta_announce_information" = "Spaces are a new way to group rooms and people. They’re not on iOS yet, but you can use them now on Web and Desktop.";
|
||||
|
||||
// MARK - Rest Time bwi
|
||||
"settings_enable_rest_time" = "Off-time";
|
||||
"room_details_main_section_rest_time" = "Off-time";
|
||||
"room_details_main_section_rest_time_global_disabled" = "Activate the off-time setting in the preferences";
|
||||
"room_details_main_section_rest_time_global" = "";
|
||||
"room_details_main_section_rest_time_locally_enabled" = "";
|
||||
"room_details_main_section_rest_time_locally_disabled" = "";
|
||||
"room_details_main_section_rest_time_restday" = "Day off today";
|
||||
"room_details_main_section_rest_time_time" = "%@ - %@";
|
||||
// MARK - Notification Times bwi
|
||||
"settings_enable_notification_times" = "Notification Times";
|
||||
|
||||
"spaces_home_space_title" = "Home";
|
||||
"spaces_add_space_title" = "Create space";
|
||||
|
||||
@@ -4947,34 +4947,6 @@ public class VectorL10n: NSObject {
|
||||
public static var roomDetailsLowPriorityTag: String {
|
||||
return VectorL10n.tr("Vector", "room_details_low_priority_tag")
|
||||
}
|
||||
/// Off-time
|
||||
public static var roomDetailsMainSectionRestTime: String {
|
||||
return VectorL10n.tr("Vector", "room_details_main_section_rest_time")
|
||||
}
|
||||
///
|
||||
public static var roomDetailsMainSectionRestTimeGlobal: String {
|
||||
return VectorL10n.tr("Vector", "room_details_main_section_rest_time_global")
|
||||
}
|
||||
/// Activate the off-time setting in the preferences
|
||||
public static var roomDetailsMainSectionRestTimeGlobalDisabled: String {
|
||||
return VectorL10n.tr("Vector", "room_details_main_section_rest_time_global_disabled")
|
||||
}
|
||||
///
|
||||
public static var roomDetailsMainSectionRestTimeLocallyDisabled: String {
|
||||
return VectorL10n.tr("Vector", "room_details_main_section_rest_time_locally_disabled")
|
||||
}
|
||||
///
|
||||
public static var roomDetailsMainSectionRestTimeLocallyEnabled: String {
|
||||
return VectorL10n.tr("Vector", "room_details_main_section_rest_time_locally_enabled")
|
||||
}
|
||||
/// Day off today
|
||||
public static var roomDetailsMainSectionRestTimeRestday: String {
|
||||
return VectorL10n.tr("Vector", "room_details_main_section_rest_time_restday")
|
||||
}
|
||||
/// %@ - %@
|
||||
public static func roomDetailsMainSectionRestTimeTime(_ p1: String, _ p2: String) -> String {
|
||||
return VectorL10n.tr("Vector", "room_details_main_section_rest_time_time", p1, p2)
|
||||
}
|
||||
/// Mute notifications
|
||||
public static var roomDetailsMuteNotifs: String {
|
||||
return VectorL10n.tr("Vector", "room_details_mute_notifs")
|
||||
@@ -6887,6 +6859,10 @@ public class VectorL10n: NSObject {
|
||||
public static var settingsEnableInappNotifications: String {
|
||||
return VectorL10n.tr("Vector", "settings_enable_inapp_notifications")
|
||||
}
|
||||
/// Notification Times
|
||||
public static var settingsEnableNotificationTimes: String {
|
||||
return VectorL10n.tr("Vector", "settings_enable_notification_times")
|
||||
}
|
||||
/// Notifications on this device
|
||||
public static var settingsEnablePushNotif: String {
|
||||
return VectorL10n.tr("Vector", "settings_enable_push_notif")
|
||||
@@ -6899,10 +6875,6 @@ public class VectorL10n: NSObject {
|
||||
public static var settingsEnableRageshake: String {
|
||||
return VectorL10n.tr("Vector", "settings_enable_rageshake")
|
||||
}
|
||||
/// Off-time
|
||||
public static var settingsEnableRestTime: String {
|
||||
return VectorL10n.tr("Vector", "settings_enable_rest_time")
|
||||
}
|
||||
/// Show room events
|
||||
public static var settingsEnableRoomAvatar: String {
|
||||
return VectorL10n.tr("Vector", "settings_enable_room_avatar")
|
||||
|
||||
@@ -199,8 +199,66 @@ class RiotSharedSettings: NSObject {
|
||||
return session.setAccountData(allowedWidgetsDict, forType: Settings.allowedWidgets, success: success, failure: failure)
|
||||
}
|
||||
|
||||
// MARK: Top Banner Features
|
||||
// MARK: Notification Times
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
func fetchNotificationTimes() {
|
||||
guard let dict = getAccountData(forEventType: "de.bwi.notification_times") else {
|
||||
return
|
||||
}
|
||||
|
||||
NotificationTimes.shared.isEnabled = (dict["is_enabled"] as? Bool) ?? false
|
||||
|
||||
if let entries = dict["entries"] as? [[String: Any]], entries.count == 7 {
|
||||
for i in 0...6 {
|
||||
let weekday = NotificationTimes.shared.weekday(index: i)
|
||||
weekday.isEnabled = (entries[i]["is_enabled"] as? Bool) ?? false
|
||||
if let fromHour = entries[i]["from_hour"] as? Int, let fromMinute = entries[i]["from_minute"] as? Int {
|
||||
weekday.startTime = Date.from(hour: fromHour, minute: fromMinute)
|
||||
}
|
||||
if let toHour = entries[i]["to_hour"] as? Int, let toMinute = entries[i]["to_minute"] as? Int {
|
||||
weekday.endTime = Date.from(hour: toHour, minute: toMinute)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let rooms = dict["rooms"] as? [[String: Any]] {
|
||||
NotificationTimes.shared.rooms = [:]
|
||||
|
||||
for room in rooms {
|
||||
if let roomID = room["room_id"] as? String, let isEnabled = room["is_enabled"] as? Bool {
|
||||
NotificationTimes.shared.rooms[roomID] = isEnabled
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
func storeNotificationTimes(success: @escaping () -> Void, failure: @escaping (Error?) -> Void) -> MXHTTPOperation? {
|
||||
let eventType = "de.bwi.notification_times"
|
||||
var entries: [[String: Any]] = []
|
||||
for i in 0...6 {
|
||||
let weekday = NotificationTimes.shared.weekday(index: i)
|
||||
let calender = Calendar.current
|
||||
let fromHour = calender.component(.hour, from: weekday.startTime)
|
||||
let fromMinute = calender.component(.minute, from: weekday.startTime)
|
||||
let toHour = calender.component(.hour, from: weekday.endTime)
|
||||
let toMinute = calender.component(.minute, from: weekday.endTime)
|
||||
|
||||
let entry: [String: Any] = ["is_enabled": weekday.isEnabled, "from_our": fromHour, "from_minute": fromMinute, "to_hour": toHour, "to_minute": toMinute]
|
||||
entries.append(entry)
|
||||
}
|
||||
|
||||
var rooms: [[String: Any]] = []
|
||||
for room in NotificationTimes.shared.rooms {
|
||||
rooms.append(["room_id": room.key, "is_enabled": room.value])
|
||||
}
|
||||
|
||||
let dict: [String: Any] = ["is_enabled": NotificationTimes.shared.isEnabled, "entries": entries, "rooms": rooms]
|
||||
return session.setAccountData(dict, forType: eventType, success: success, failure: failure)
|
||||
}
|
||||
|
||||
// MARK: Top Banner Features
|
||||
|
||||
func topBanner(for feature: String) -> Bool {
|
||||
guard let featuresDict = getAccountData(forEventType: "de.bwi.top_banner_features") else {
|
||||
return true
|
||||
|
||||
@@ -1168,8 +1168,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
|
||||
UIContextualAction *muteAction = nil;
|
||||
|
||||
if (BuildSettings.featureWorkTime) {
|
||||
muteAction = [self muteActionWithWorkTime:room];
|
||||
if (BwiBuildSettings.bwiNotificationTimes) {
|
||||
muteAction = [self muteActionWithNotificationTime:room];
|
||||
} else {
|
||||
BOOL isMuted = room.isMute || room.isMentionsOnly;
|
||||
|
||||
@@ -1201,7 +1201,6 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
notificationImage = [UIImage imageNamed:@"room_action_notification"];
|
||||
}
|
||||
|
||||
// $$$
|
||||
notificationImage = [notificationImage vc_tintedImageUsingColor:isMuted ? unselectedColor : selectedColor];
|
||||
muteAction.image = [notificationImage vc_notRenderedImage];
|
||||
}
|
||||
@@ -2483,19 +2482,33 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
|
||||
#pragma mark - Bwi Rest Time
|
||||
|
||||
- (UIContextualAction*) muteActionWithWorkTime:(MXRoom*)room {
|
||||
BOOL isMuted = room.isMute || room.isMentionsOnly;
|
||||
BOOL isWorkTime = [self isWorkTimeActive:room];
|
||||
- (UIContextualAction*) muteActionWithNotificationTime:(MXRoom*)room {
|
||||
if (@available(iOS 14.0, *)) {
|
||||
RiotSharedSettings *sharedSettings = [[RiotSharedSettings alloc] initWithSession:room.mxSession];
|
||||
[sharedSettings fetchNotificationTimes];
|
||||
}
|
||||
|
||||
BOOL isMuted = room.isMute || room.isMentionsOnly;
|
||||
BOOL isRoomNotificationTimesActive = [self isNotficationTimesActive:room];
|
||||
|
||||
UIContextualAction *muteAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive
|
||||
title:@""
|
||||
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
|
||||
[self muteEditedRoomNotificationsWithWorkTime:!isMuted];
|
||||
|
||||
if ([BuildSettings roomSettingsScreenShowNotificationsV2])
|
||||
{
|
||||
[self changeEditedRoomNotificationSettings];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self muteEditedRoomNotifications:!isMuted];
|
||||
}
|
||||
|
||||
completionHandler(YES);
|
||||
}];
|
||||
muteAction.backgroundColor = ThemeService.shared.theme.baseColor;
|
||||
muteAction.image =[self editedRoomNotififcationImageForMuted:isMuted andWorkTime:isWorkTime];
|
||||
|
||||
muteAction.image =[self editedRoomNotififcationImageForMuted:isMuted andRoomNotificationTimeActive:isRoomNotificationTimesActive];
|
||||
|
||||
return muteAction;
|
||||
}
|
||||
|
||||
@@ -2530,11 +2543,11 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
[self cancelEditionMode:self->isRefreshPending];
|
||||
|
||||
}];
|
||||
WorkTimeService *service = [WorkTimeService workTimeService:self.mainSession.myUserId];
|
||||
|
||||
if ([service isWorkTimeGlobalyEnabled]) {
|
||||
[service activateWorkTimeInRoom:editedRoomId];
|
||||
}
|
||||
// WorkTimeService *service = [WorkTimeService workTimeService:self.mainSession.myUserId];
|
||||
//
|
||||
// if ([service isWorkTimeGlobalyEnabled]) {
|
||||
// [service activateWorkTimeInRoom:editedRoomId];
|
||||
// }
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2545,29 +2558,25 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) isWorkTimeActive:(MXRoom*)room {
|
||||
WorkTimeService *service = [WorkTimeService workTimeService:self.mainSession.myUser.userId];
|
||||
|
||||
if ([service isWorkTimeGlobalyEnabled]) {
|
||||
if ([service.store isWorkTimeRoom:room.roomId]) {
|
||||
return [service.store isWorkTimeInRoomActive:room.roomId];
|
||||
} else {
|
||||
return !room.isDirect;
|
||||
}
|
||||
- (BOOL) isNotficationTimesActive:(MXRoom*)room {
|
||||
if (@available(iOS 14.0, *)) {
|
||||
return [[NotificationTimes shared] isEnabled] && [[NotificationTimes shared] isEnabledForRoomWithRoomID:room.roomId isDirect:room.isDirect];
|
||||
} else {
|
||||
return NO;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
- (UIImage*)editedRoomNotififcationImageForMuted:(BOOL)isMuted andWorkTime:(BOOL)WorkTimeActive {
|
||||
- (UIImage*)editedRoomNotififcationImageForMuted:(BOOL)isMuted andRoomNotificationTimeActive:(BOOL)isRoomNotificationTimeActive {
|
||||
UIImage *image = nil;
|
||||
|
||||
if (WorkTimeActive && !isMuted ) {
|
||||
image = [[UIImage imageNamed:@"room_action_resttime"] vc_tintedImageUsingColor:isMuted ? ThemeService.shared.theme.tabBarUnselectedItemTintColor
|
||||
: ThemeService.shared.theme.tintColor];
|
||||
} else {
|
||||
image = [[UIImage imageNamed:@"room_action_notification"] vc_tintedImageUsingColor:isMuted ? ThemeService.shared.theme.tabBarUnselectedItemTintColor
|
||||
: ThemeService.shared.theme.tintColor];
|
||||
if (isRoomNotificationTimeActive && !isMuted) {
|
||||
image = [[UIImage imageNamed:@"room_action_resttime"] vc_tintedImageUsingColor:ThemeService.shared.theme.tintColor];
|
||||
}
|
||||
else if (isMuted) {
|
||||
image = [[UIImage imageNamed:@"room_action_notification_muted"] vc_tintedImageUsingColor: ThemeService.shared.theme.tabBarUnselectedItemTintColor];
|
||||
}
|
||||
else {
|
||||
image = [[UIImage imageNamed:@"room_action_notification"] vc_tintedImageUsingColor: ThemeService.shared.theme.tintColor];
|
||||
}
|
||||
|
||||
return [image vc_notRenderedImage];
|
||||
|
||||
@@ -114,7 +114,6 @@ NSString *const kRoomSettingsNameKey = @"kRoomSettingsNameKey";
|
||||
NSString *const kRoomSettingsTopicKey = @"kRoomSettingsTopicKey";
|
||||
NSString *const kRoomSettingsTagKey = @"kRoomSettingsTagKey";
|
||||
NSString *const kRoomSettingsMuteNotifKey = @"kRoomSettingsMuteNotifKey";
|
||||
NSString *const kRoomSettingsWorkTimeNotifKey = @"kRoomSettingsWorkTimeNotifKey";
|
||||
NSString *const kRoomSettingsDirectChatKey = @"kRoomSettingsDirectChatKey";
|
||||
NSString *const kRoomSettingsJoinRuleKey = @"kRoomSettingsJoinRuleKey";
|
||||
NSString *const kRoomSettingsGuestAccessKey = @"kRoomSettingsGuestAccessKey";
|
||||
@@ -127,6 +126,7 @@ NSString *const kRoomSettingsNewRelatedGroupKey = @"kRoomSettingsNewRelatedGroup
|
||||
NSString *const kRoomSettingsRemovedRelatedGroupKey = @"kRoomSettingsRemovedRelatedGroupKey";
|
||||
NSString *const kRoomSettingsEncryptionKey = @"kRoomSettingsEncryptionKey";
|
||||
NSString *const kRoomSettingsEncryptionBlacklistUnverifiedDevicesKey = @"kRoomSettingsEncryptionBlacklistUnverifiedDevicesKey";
|
||||
NSString *const kRoomSettingsNotificationTimesKey = @"kRoomSettingsNotificationTimesKey";
|
||||
|
||||
NSString *const kRoomSettingsNameCellViewIdentifier = @"kRoomSettingsNameCellViewIdentifier";
|
||||
NSString *const kRoomSettingsTopicCellViewIdentifier = @"kRoomSettingsTopicCellViewIdentifier";
|
||||
@@ -490,6 +490,14 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
|
||||
|
||||
- (void)updateSections
|
||||
{
|
||||
if (@available(iOS 14.0, *)) {
|
||||
MXSession *session = [AppDelegate theDelegate].mxSessions.firstObject;
|
||||
if(session) {
|
||||
RiotSharedSettings *sharedSettings = [[RiotSharedSettings alloc] initWithSession:session];
|
||||
[sharedSettings fetchNotificationTimes];
|
||||
}
|
||||
}
|
||||
|
||||
if(mxRoom.isPersonalNotesRoom) {
|
||||
[self updateSectionsAsPersonalNotes];
|
||||
return;
|
||||
@@ -546,7 +554,7 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
|
||||
{
|
||||
[sectionMain addRowWithTag:ROOM_SETTINGS_MAIN_SECTION_ROW_DIRECT_CHAT];
|
||||
}
|
||||
if (BuildSettings.featureWorkTime)
|
||||
if (BwiBuildSettings.bwiNotificationTimes)
|
||||
{
|
||||
[sectionMain addRowWithTag:ROOM_SETTINGS_MAIN_SECTION_ROW_REST_TIME];
|
||||
[sectionMain addRowWithTag:ROOM_SETTINGS_MAIN_SECTION_ROW_REST_TIME_INFO];
|
||||
@@ -2210,6 +2218,26 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
|
||||
BOOL blacklistUnverifiedDevices = [((NSNumber*)updatedItemsDict[kRoomSettingsEncryptionBlacklistUnverifiedDevicesKey]) boolValue];
|
||||
[mxRoom.mxSession.crypto setBlacklistUnverifiedDevicesInRoom:mxRoom.roomId blacklist:blacklistUnverifiedDevices];
|
||||
}
|
||||
|
||||
// Notification times toggle
|
||||
if (updatedItemsDict[kRoomSettingsNotificationTimesKey])
|
||||
{
|
||||
if (@available(iOS 14.0, *)) {
|
||||
bool isON = [[updatedItemsDict[kRoomSettingsNotificationTimesKey] stringValue] isEqualToString:@"ON"];
|
||||
if(isON) {
|
||||
[[NotificationTimes shared] enableForRoomWithRoomID:self.roomId];
|
||||
} else {
|
||||
[[NotificationTimes shared] disableForRoomWithRoomID:self.roomId];
|
||||
}
|
||||
|
||||
RiotSharedSettings *sharedSetting = [[RiotSharedSettings alloc] initWithSession:self.mainSession];
|
||||
(void)[sharedSetting storeNotificationTimesWithSuccess:^{} failure:^(NSError *error) {
|
||||
MXLogWarning(@"[RoomSettingsViewController] Cannot store value for notification times toggle.")
|
||||
}];
|
||||
}
|
||||
|
||||
[updatedItemsDict removeObjectForKey:kRoomSettingsNotificationTimesKey];
|
||||
}
|
||||
}
|
||||
|
||||
[self getNavigationItem].rightBarButtonItem.enabled = NO;
|
||||
@@ -2309,10 +2337,10 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
|
||||
cell = roomNotifCell;
|
||||
}
|
||||
else if( row == ROOM_SETTINGS_MAIN_SECTION_ROW_REST_TIME) {
|
||||
cell = [self cellForWorkTimeSwitch:tableView indexPath:indexPath];
|
||||
cell = [self cellForNotificationTimesSwitch:tableView indexPath:indexPath];
|
||||
}
|
||||
else if( row == ROOM_SETTINGS_MAIN_SECTION_ROW_REST_TIME_INFO) {
|
||||
cell = [self cellForWorkTimeInfo:tableView indexPath:indexPath];
|
||||
cell = [self cellForNotificationTimesInfo:tableView indexPath:indexPath];
|
||||
}
|
||||
else if (row == ROOM_SETTINGS_MAIN_SECTION_ROW_DIRECT_CHAT)
|
||||
{
|
||||
@@ -4308,35 +4336,34 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
|
||||
return roomAccessToggleCell;
|
||||
}
|
||||
|
||||
- (UITableViewCell*) cellForWorkTimeSwitch:(UITableView*)tableView indexPath:(NSIndexPath*)indexPath {
|
||||
MXKTableViewCellWithLabelAndSwitch *workTimeToggleCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
- (UITableViewCell*) cellForNotificationTimesSwitch:(UITableView*)tableView indexPath:(NSIndexPath*)indexPath {
|
||||
MXKTableViewCellWithLabelAndSwitch *toggleCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
|
||||
[workTimeToggleCell.mxkSwitch addTarget:self action:@selector(toggleWorkTime:) forControlEvents:UIControlEventValueChanged];
|
||||
[toggleCell.mxkSwitch addTarget:self action:@selector(toggleNotificationTimes:) forControlEvents:UIControlEventValueChanged];
|
||||
|
||||
workTimeToggleCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_main_section_rest_time", @"Vector", nil);
|
||||
workTimeToggleCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor;
|
||||
workTimeToggleCell.mxkSwitch.on = [self isWorkTimeSwitchOn];
|
||||
workTimeToggleCell.mxkSwitch.enabled = [self isWorkTimeSwitchEnabled];
|
||||
toggleCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_enable_notification_times", @"Vector", nil);
|
||||
toggleCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor;
|
||||
toggleCell.mxkSwitch.on = [self isNotificationTimesSwitchOn];
|
||||
toggleCell.mxkSwitch.enabled = [self isNotificationTimesSwitchEnabled];
|
||||
|
||||
return workTimeToggleCell;
|
||||
return toggleCell;
|
||||
}
|
||||
|
||||
- (UITableViewCell*) cellForWorkTimeInfo:(UITableView*)tableView indexPath:(NSIndexPath*)indexPath {
|
||||
MXKTableViewCell *workTimeInfoCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier] forIndexPath:indexPath];
|
||||
|
||||
if (!workTimeInfoCell)
|
||||
- (UITableViewCell*) cellForNotificationTimesInfo:(UITableView*)tableView indexPath:(NSIndexPath*)indexPath {
|
||||
MXKTableViewCell *notificationTimesInfoCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier] forIndexPath:indexPath];
|
||||
if (!notificationTimesInfoCell)
|
||||
{
|
||||
workTimeInfoCell = [[MXKTableViewCell alloc] init];
|
||||
notificationTimesInfoCell = [[MXKTableViewCell alloc] init];
|
||||
}
|
||||
|
||||
workTimeInfoCell.textLabel.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
workTimeInfoCell.textLabel.font = [UIFont systemFontOfSize:15.0];
|
||||
workTimeInfoCell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
workTimeInfoCell.userInteractionEnabled = NO;
|
||||
workTimeInfoCell.textLabel.text = [self textForWorkTimeInfoCell];
|
||||
workTimeInfoCell.textLabel.adjustsFontSizeToFitWidth = YES;
|
||||
|
||||
return workTimeInfoCell;
|
||||
notificationTimesInfoCell.textLabel.textColor = ThemeService.shared.theme.textPrimaryColor;
|
||||
notificationTimesInfoCell.textLabel.font = [UIFont systemFontOfSize:15.0];
|
||||
notificationTimesInfoCell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
notificationTimesInfoCell.userInteractionEnabled = NO;
|
||||
notificationTimesInfoCell.textLabel.text = NSLocalizedStringFromTable(@"bwi_notification_times_toggle_description", @"Bwi", @"");
|
||||
notificationTimesInfoCell.textLabel.numberOfLines = 0;
|
||||
|
||||
return notificationTimesInfoCell;
|
||||
}
|
||||
|
||||
- (void)toggleDirectoryAccessBW:(UISwitch*)theSwitch
|
||||
@@ -4366,63 +4393,29 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
|
||||
[self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0);
|
||||
}
|
||||
|
||||
- (void)toggleWorkTime:(UISwitch*)theSwitch {
|
||||
NSLog(@"Toggle Worktime");
|
||||
- (void)toggleNotificationTimes:(UISwitch*)theSwitch {
|
||||
NSLog(@"Toggle Notification Times");
|
||||
|
||||
WorkTimeService *service = [WorkTimeService workTimeService:self.mainSession.myUser.userId];
|
||||
|
||||
updatedItemsDict[kRoomSettingsWorkTimeNotifKey] = @(theSwitch.on);
|
||||
|
||||
if (theSwitch.on) {
|
||||
[service activateWorkTimeInRoom:self.roomId];
|
||||
} else {
|
||||
[service deactivateWorkTimeInRoom:self.roomId];
|
||||
if (@available(iOS 14.0, *)) {
|
||||
updatedItemsDict[kRoomSettingsNotificationTimesKey] = theSwitch.on ? @"ON" : @"OFF";
|
||||
[self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0);
|
||||
}
|
||||
|
||||
[self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0);
|
||||
}
|
||||
|
||||
- (NSString*) textForWorkTimeInfoCell {
|
||||
WorkTimeService *service = [WorkTimeService workTimeService:self.mainSession.myUser.userId];
|
||||
NSString *text = @"";
|
||||
|
||||
if (service.isWorkTimeGlobalyEnabled) {
|
||||
if ([service.store isWorkTimeRoom:self.roomId] ) {
|
||||
if ([service.store isWorkTimeInRoomActive:self.roomId]) {
|
||||
text = [NSString stringWithFormat:@"%@ %@", NSLocalizedStringFromTable(@"room_details_main_section_rest_time_locally_enabled", @"Vector", nil), [service localizedWorkTime]];
|
||||
} else {
|
||||
text = NSLocalizedStringFromTable(@"room_details_main_section_rest_time_locally_disabled", @"Vector", nil);
|
||||
}
|
||||
} else {
|
||||
text = [NSString stringWithFormat:@"%@ %@", NSLocalizedStringFromTable(@"room_details_main_section_rest_time_global", @"Vector", nil), [service localizedWorkTime]];
|
||||
}
|
||||
- (BOOL) isNotificationTimesSwitchOn {
|
||||
if (@available(iOS 14.0, *)) {
|
||||
RiotSharedSettings *sharedSetting = [[RiotSharedSettings alloc] initWithSession:self.mainSession];
|
||||
[sharedSetting fetchNotificationTimes];
|
||||
return [[NotificationTimes shared] isEnabledForRoomWithRoomID:self.roomId isDirect:mxRoom.isDirect];
|
||||
} else {
|
||||
text = NSLocalizedStringFromTable(@"room_details_main_section_rest_time_global_disabled", @"Vector", nil);
|
||||
return false;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
- (BOOL) isWorkTimeSwitchOn {
|
||||
WorkTimeService *service = [WorkTimeService workTimeService:self.mainSession.myUser.userId];
|
||||
BOOL isOn = NO;
|
||||
|
||||
if (service.isWorkTimeGlobalyEnabled) {
|
||||
if ([service.store isWorkTimeRoom:self.roomId] ) {
|
||||
if ([service.store isWorkTimeInRoomActive:self.roomId]) {
|
||||
isOn = YES;
|
||||
}
|
||||
} else {
|
||||
isOn = !self->mxRoom.isDirect;
|
||||
}
|
||||
}
|
||||
|
||||
return isOn;
|
||||
}
|
||||
|
||||
- (BOOL) isWorkTimeSwitchEnabled {
|
||||
WorkTimeService *service = [WorkTimeService workTimeService:self.mainSession.myUser.userId];
|
||||
return service.isWorkTimeGlobalyEnabled;
|
||||
- (BOOL) isNotificationTimesSwitchEnabled {
|
||||
return !mxRoom.isDirect;
|
||||
}
|
||||
|
||||
- (void) updateSectionsAsPersonalNotes {
|
||||
|
||||
@@ -121,13 +121,13 @@ typedef NS_ENUM(NSUInteger, LINKS_SHOW_URL_PREVIEWS)
|
||||
typedef NS_ENUM(NSUInteger, NOTIFICATION_SETTINGS)
|
||||
{
|
||||
NOTIFICATION_SETTINGS_ENABLE_PUSH_INDEX = 0,
|
||||
NOTIFICATION_SETTINGS_ENABLE_REST_TIME,
|
||||
NOTIFICATION_SETTINGS_SYSTEM_SETTINGS,
|
||||
NOTIFICATION_SETTINGS_SHOW_DECODED_CONTENT,
|
||||
NOTIFICATION_SETTINGS_PIN_MISSED_NOTIFICATIONS_INDEX,
|
||||
NOTIFICATION_SETTINGS_PIN_UNREAD_INDEX,
|
||||
NOTIFICATION_SETTINGS_DEFAULT_SETTINGS_INDEX,
|
||||
NOTIFICATION_SETTINGS_MENTION_AND_KEYWORDS_SETTINGS_INDEX,
|
||||
NOTIFICATION_SETTINGS_NOTIFICATION_TIMES_INDEX,
|
||||
NOTIFICATION_SETTINGS_OTHER_SETTINGS_INDEX,
|
||||
};
|
||||
|
||||
@@ -491,11 +491,6 @@ ThreadsBetaCoordinatorBridgePresenterDelegate>
|
||||
Section *sectionNotificationSettings = [Section sectionWithTag:SECTION_TAG_NOTIFICATIONS];
|
||||
[sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_ENABLE_PUSH_INDEX];
|
||||
|
||||
if (BuildSettings.featureWorkTime)
|
||||
{
|
||||
[sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_ENABLE_REST_TIME];
|
||||
}
|
||||
|
||||
if (RiotSettings.shared.settingsScreenShowSystemSettingsOption) {
|
||||
[sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_SYSTEM_SETTINGS];
|
||||
}
|
||||
@@ -521,6 +516,9 @@ ThreadsBetaCoordinatorBridgePresenterDelegate>
|
||||
if (RiotSettings.shared.settingsNotificationsShowMentions) {
|
||||
[sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_MENTION_AND_KEYWORDS_SETTINGS_INDEX];
|
||||
}
|
||||
if (BwiBuildSettings.bwiNotificationTimes) {
|
||||
[sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_NOTIFICATION_TIMES_INDEX];
|
||||
}
|
||||
if (RiotSettings.shared.settingsNotificationsShowAdvanced) {
|
||||
[sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_OTHER_SETTINGS_INDEX];
|
||||
}
|
||||
@@ -2245,10 +2243,6 @@ ThreadsBetaCoordinatorBridgePresenterDelegate>
|
||||
|
||||
cell = labelAndSwitchCell;
|
||||
}
|
||||
else if (row == NOTIFICATION_SETTINGS_ENABLE_REST_TIME)
|
||||
{
|
||||
cell = [self cellForWorkTime:tableView indexPath:indexPath];
|
||||
}
|
||||
else if (row == NOTIFICATION_SETTINGS_SYSTEM_SETTINGS)
|
||||
{
|
||||
cell = [tableView dequeueReusableCellWithIdentifier:kSettingsViewControllerPhoneBookCountryCellId];
|
||||
@@ -2302,7 +2296,7 @@ ThreadsBetaCoordinatorBridgePresenterDelegate>
|
||||
|
||||
cell = labelAndSwitchCell;
|
||||
}
|
||||
else if (row == NOTIFICATION_SETTINGS_DEFAULT_SETTINGS_INDEX || row == NOTIFICATION_SETTINGS_MENTION_AND_KEYWORDS_SETTINGS_INDEX || row == NOTIFICATION_SETTINGS_OTHER_SETTINGS_INDEX)
|
||||
else if (row == NOTIFICATION_SETTINGS_DEFAULT_SETTINGS_INDEX || row == NOTIFICATION_SETTINGS_MENTION_AND_KEYWORDS_SETTINGS_INDEX || row == NOTIFICATION_SETTINGS_OTHER_SETTINGS_INDEX || row == NOTIFICATION_SETTINGS_NOTIFICATION_TIMES_INDEX)
|
||||
{
|
||||
cell = [self getDefaultTableViewCell:tableView];
|
||||
if (row == NOTIFICATION_SETTINGS_DEFAULT_SETTINGS_INDEX)
|
||||
@@ -2313,6 +2307,10 @@ ThreadsBetaCoordinatorBridgePresenterDelegate>
|
||||
{
|
||||
cell.textLabel.text = [VectorL10n settingsMentionsAndKeywords];
|
||||
}
|
||||
else if (row == NOTIFICATION_SETTINGS_NOTIFICATION_TIMES_INDEX)
|
||||
{
|
||||
cell.textLabel.text = [VectorL10n settingsEnableNotificationTimes];
|
||||
}
|
||||
else if (row == NOTIFICATION_SETTINGS_OTHER_SETTINGS_INDEX)
|
||||
{
|
||||
cell.textLabel.text = [VectorL10n settingsOther];
|
||||
@@ -3264,6 +3262,9 @@ ThreadsBetaCoordinatorBridgePresenterDelegate>
|
||||
case NOTIFICATION_SETTINGS_MENTION_AND_KEYWORDS_SETTINGS_INDEX:
|
||||
[self showNotificationSettings:NotificationSettingsScreenMentionsAndKeywords];
|
||||
break;
|
||||
case NOTIFICATION_SETTINGS_NOTIFICATION_TIMES_INDEX:
|
||||
[self showNotificationTimesSettings];
|
||||
break;
|
||||
case NOTIFICATION_SETTINGS_OTHER_SETTINGS_INDEX:
|
||||
[self showNotificationSettings:NotificationSettingsScreenOther];
|
||||
break;
|
||||
@@ -4356,7 +4357,6 @@ ThreadsBetaCoordinatorBridgePresenterDelegate>
|
||||
RiotSettings.shared.showNSFWPublicRooms = sender.isOn;
|
||||
}
|
||||
|
||||
|
||||
- (void)showDeveloperSettings
|
||||
{
|
||||
if (@available(iOS 14.0, *)) {
|
||||
@@ -4365,6 +4365,14 @@ ThreadsBetaCoordinatorBridgePresenterDelegate>
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showNotificationTimesSettings
|
||||
{
|
||||
if (@available(iOS 14.0, *)) {
|
||||
UIViewController *notificationTimesViewController = [NotificationTimesViewController makeViewControllerWithSession:self.mainSession];
|
||||
[self pushViewController:notificationTimesViewController];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)toggleEnableRoomMessageBubbles:(UISwitch *)sender
|
||||
{
|
||||
RiotSettings.shared.roomScreenEnableMessageBubbles = sender.isOn;
|
||||
@@ -5334,26 +5342,6 @@ ThreadsBetaCoordinatorBridgePresenterDelegate>
|
||||
|
||||
#pragma mark - bwi Messenger Additions
|
||||
|
||||
- (UITableViewCell*) cellForWorkTime:(UITableView*)tableView indexPath:(NSIndexPath*)indexPath {
|
||||
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
|
||||
WorkTimeService *service = [WorkTimeService workTimeService:self.mainSession.myUser.userId];
|
||||
|
||||
labelAndSwitchCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_enable_rest_time", @"Vector", nil);
|
||||
labelAndSwitchCell.mxkSwitch.on = [service isWorkTimeGlobalyEnabled];
|
||||
labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor;
|
||||
labelAndSwitchCell.mxkSwitch.enabled = YES;
|
||||
[labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleRestService:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
return labelAndSwitchCell;
|
||||
}
|
||||
|
||||
- (void)toggleRestService:(UISwitch*)theSwitch
|
||||
{
|
||||
WorkTimeService *service = [WorkTimeService workTimeService:self.mainSession.myUser.userId];
|
||||
[service enableWorkTime:theSwitch.isOn];
|
||||
}
|
||||
|
||||
- (UITableViewCell*) cellForPersonalNotes:(UITableView*)tableView indexPath:(NSIndexPath*)indexPath {
|
||||
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
setupAnalytics()
|
||||
|
||||
UNUserNotificationCenter.current().removeUnwantedNotifications()
|
||||
|
||||
|
||||
// check if this is a Matrix notification
|
||||
guard let roomId = userInfo["room_id"] as? String, let eventId = userInfo["event_id"] as? String else {
|
||||
// it's not a Matrix notification, do not change the content
|
||||
@@ -121,6 +121,14 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
return
|
||||
}
|
||||
|
||||
// check if the event arrived outside the user defined working time for this room
|
||||
guard !isRoomMuted(roomID: roomId) else {
|
||||
// it's not a Matrix notification, do not change the content
|
||||
MXLog.debug("[NotificationService] didReceiveRequest: This is not a Matrix notification.")
|
||||
contentHandler(UNNotificationContent())
|
||||
return
|
||||
}
|
||||
|
||||
// save this content as fallback content
|
||||
guard let content = request.content.mutableCopy() as? UNMutableNotificationContent else {
|
||||
return
|
||||
@@ -184,6 +192,44 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
}
|
||||
}
|
||||
|
||||
private func isRoomMuted(roomID: String) -> Bool {
|
||||
let sharedUserDefaults = MXKAppSettings.standard().sharedUserDefaults
|
||||
|
||||
if #available(iOSApplicationExtension 14.0, *) {
|
||||
guard let data = sharedUserDefaults?.data(forKey: NotificationTimes.sharedUserDefaultsKey), let notificationTimes = try? JSONDecoder().decode(NotificationTimes.self, from: data) else {
|
||||
return false
|
||||
}
|
||||
|
||||
let now = Date()
|
||||
|
||||
let calendar = Calendar.current
|
||||
let weekday: NotificationTimesWeekday
|
||||
switch calendar.component(.weekday, from: now) {
|
||||
case 1: // sunday
|
||||
weekday = notificationTimes.weekday(index: 6)
|
||||
case 2: // monday
|
||||
weekday = notificationTimes.weekday(index: 0)
|
||||
case 3: // tuesday
|
||||
weekday = notificationTimes.weekday(index: 1)
|
||||
case 4: // wednesday
|
||||
weekday = notificationTimes.weekday(index: 2)
|
||||
case 5: // thursday
|
||||
weekday = notificationTimes.weekday(index: 3)
|
||||
case 6: // friday
|
||||
weekday = notificationTimes.weekday(index: 4)
|
||||
case 7: // saturday
|
||||
weekday = notificationTimes.weekday(index: 5)
|
||||
default:
|
||||
MXLog.error("[NotificationService] isRoomMuted failed because of an invalid day component.")
|
||||
return false
|
||||
}
|
||||
|
||||
return notificationTimes.isEnabled && weekday.isEnabled && weekday.startTime <= now && weekday.endTime >= now
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private func setupAnalytics(){
|
||||
// Configure our analytics. It will start if the option is enabled
|
||||
let analytics = Analytics.shared
|
||||
|
||||
@@ -10,5 +10,7 @@
|
||||
<array>
|
||||
<string>$(KEYCHAIN_ACCESS_GROUP)</string>
|
||||
</array>
|
||||
<key>com.apple.developer.usernotifications.filtering</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -40,6 +40,10 @@ targets:
|
||||
- path: ../bwi/AppConfig
|
||||
- path: ../bwi/ServerURLs
|
||||
- path: ../bwi/SecureStorage
|
||||
- path: ../bwi/NotificationTimes/NotificationTimes.swift
|
||||
- path: ../bwi/NotificationTimes/NotificationTimesRoomSettings.swift
|
||||
- path: ../bwi/NotificationTimes/NotificationTimesWeekday.swift
|
||||
- path: ../bwi/NotificationTimes/Date+fromHourMinute.swift
|
||||
- path: ../bwi/BwiBuildSettings.swift
|
||||
- path: ../Config/BwiSettings.swift
|
||||
- path: ../Riot/Managers/Settings/RiotSettings.swift
|
||||
|
||||
@@ -53,6 +53,8 @@ final class BwiBuildSettings: NSObject {
|
||||
static let bwiSettingsShowSecureBackupSection = false
|
||||
static let bwiSettingsShowCrossSigningSection = false
|
||||
|
||||
static let bwiNotificationTimes = true
|
||||
|
||||
static let bwiUserLabelsAdminSettingsVisible = true
|
||||
static let bwiUserLabelsMemberDetailsVisible = true
|
||||
static let bwiUserLabelsParticipantsVisible = true
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import SwiftUI
|
||||
|
||||
|
||||
/// Helper class for making our SwiftUI view available to ObjectiveC
|
||||
@objcMembers class DeveloperSettingsViewController: NSObject {
|
||||
|
||||
@@ -26,6 +27,8 @@ import SwiftUI
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
struct DeveloperSettingsView: View {
|
||||
let session: MXSession?
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//
|
||||
/*
|
||||
* Copyright (c) 2021 BWI GmbH
|
||||
* Copyright (c) 2022 BWI GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,17 +17,16 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct WorkTimeInRoom : Codable, Hashable, Equatable {
|
||||
var userId: String
|
||||
var roomId: String
|
||||
var isWorkTimeActive: Bool
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(userId)
|
||||
hasher.combine(roomId)
|
||||
}
|
||||
|
||||
static func == (lhs: Self, rhs: Self) -> Bool {
|
||||
return lhs.roomId == rhs.roomId && lhs.userId == rhs.userId
|
||||
extension Date {
|
||||
static func from(hour: Int, minute: Int) -> Date {
|
||||
let gregorianCalendar = NSCalendar(calendarIdentifier: .gregorian)!
|
||||
|
||||
var dateComponents = DateComponents()
|
||||
dateComponents.hour = hour
|
||||
dateComponents.minute = minute
|
||||
|
||||
let date = gregorianCalendar.date(from: dateComponents)!
|
||||
return date
|
||||
}
|
||||
}
|
||||
|
||||
96
bwi/NotificationTimes/NotificationTimes.swift
Normal file
96
bwi/NotificationTimes/NotificationTimes.swift
Normal file
@@ -0,0 +1,96 @@
|
||||
//
|
||||
/*
|
||||
* Copyright (c) 2022 BWI GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
@objcMembers class NotificationTimes: NSObject, Codable {
|
||||
static let shared = NotificationTimes()
|
||||
static let sharedUserDefaultsKey = "notificationTimes"
|
||||
|
||||
var isEnabled: Bool
|
||||
var monday, tuesday, wednesday, thursday, friday, saturday, sunday : NotificationTimesWeekday
|
||||
var rooms: [String : Bool]
|
||||
|
||||
func weekday(index: Int) -> NotificationTimesWeekday {
|
||||
switch index {
|
||||
case 0:
|
||||
return monday
|
||||
case 1:
|
||||
return tuesday
|
||||
case 2:
|
||||
return wednesday
|
||||
case 3:
|
||||
return thursday
|
||||
case 4:
|
||||
return friday
|
||||
case 5:
|
||||
return saturday
|
||||
case 6:
|
||||
return sunday
|
||||
default:
|
||||
assertionFailure("weekday index outside range 0...6")
|
||||
return monday
|
||||
}
|
||||
}
|
||||
|
||||
override init() {
|
||||
isEnabled = false
|
||||
|
||||
monday = NotificationTimesWeekday(id: 0,
|
||||
name: NSLocalizedString("bwi_notification_times_monday", tableName: "Bwi", comment: ""),
|
||||
shortName: NSLocalizedString("bwi_notification_times_monday_short", tableName: "Bwi", comment: ""))
|
||||
tuesday = NotificationTimesWeekday(id: 1,
|
||||
name: NSLocalizedString("bwi_notification_times_tuesday", tableName: "Bwi", comment: ""),
|
||||
shortName: NSLocalizedString("bwi_notification_times_tuesday_short", tableName: "Bwi", comment: ""))
|
||||
wednesday = NotificationTimesWeekday(id: 2,
|
||||
name: NSLocalizedString("bwi_notification_times_wednesday", tableName: "Bwi", comment: ""),
|
||||
shortName: NSLocalizedString("bwi_notification_times_wednesday_short", tableName: "Bwi", comment: ""))
|
||||
thursday = NotificationTimesWeekday(id: 3,
|
||||
name: NSLocalizedString("bwi_notification_times_thursday", tableName: "Bwi", comment: ""),
|
||||
shortName: NSLocalizedString("bwi_notification_times_thursday_short", tableName: "Bwi", comment: ""))
|
||||
friday = NotificationTimesWeekday(id: 4,
|
||||
name: NSLocalizedString("bwi_notification_times_friday", tableName: "Bwi", comment: ""),
|
||||
shortName: NSLocalizedString("bwi_notification_times_friday_short", tableName: "Bwi", comment: ""))
|
||||
saturday = NotificationTimesWeekday(id: 5,
|
||||
name: NSLocalizedString("bwi_notification_times_saturday", tableName: "Bwi", comment: ""),
|
||||
shortName: NSLocalizedString("bwi_notification_times_saturday_short", tableName: "Bwi", comment: ""))
|
||||
sunday = NotificationTimesWeekday(id: 6,
|
||||
name: NSLocalizedString("bwi_notification_times_sunday", tableName: "Bwi", comment: ""),
|
||||
shortName: NSLocalizedString("bwi_notification_times_sunday_short", tableName: "Bwi", comment: ""))
|
||||
|
||||
rooms = [:]
|
||||
}
|
||||
|
||||
func isEnabledForRoom(roomID: String, isDirect: Bool) -> Bool {
|
||||
if isDirect {
|
||||
return rooms[roomID] ?? false
|
||||
} else {
|
||||
return rooms[roomID] ?? true
|
||||
}
|
||||
}
|
||||
|
||||
func enableForRoom(roomID: String) {
|
||||
rooms[roomID] = true
|
||||
}
|
||||
|
||||
func disableForRoom(roomID: String) {
|
||||
rooms[roomID] = false
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
//
|
||||
/*
|
||||
* Copyright (c) 2021 BWI GmbH
|
||||
* Copyright (c) 2022 BWI GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +17,12 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct WorkTimeUser : Codable {
|
||||
let WorkTime : WorkTime
|
||||
let userId : String
|
||||
struct NotificationTimesRoomSettings: Codable {
|
||||
var roomID: String
|
||||
var enabled: Bool
|
||||
|
||||
private enum CodingKeys : String, CodingKey {
|
||||
case roomID = "room_id"
|
||||
case enabled
|
||||
}
|
||||
}
|
||||
272
bwi/NotificationTimes/NotificationTimesView.swift
Normal file
272
bwi/NotificationTimes/NotificationTimesView.swift
Normal file
@@ -0,0 +1,272 @@
|
||||
//
|
||||
/*
|
||||
* Copyright (c) 2022 BWI GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import SwiftUI
|
||||
|
||||
|
||||
/// Helper class for making our SwiftUI view available to ObjectiveC
|
||||
@objcMembers class NotificationTimesViewController: NSObject {
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
class func makeViewController(session: MXSession) -> UIViewController {
|
||||
return UIHostingController(rootView: NotificationTimesView(session: session))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
struct NotificationTimesView: View {
|
||||
@State var isOn = NotificationTimes.shared.isEnabled
|
||||
@State var selectedDay: Int = 0
|
||||
@State var weekdays = [NotificationTimes.shared.monday, NotificationTimes.shared.tuesday, NotificationTimes.shared.wednesday, NotificationTimes.shared.thursday, NotificationTimes.shared.friday, NotificationTimes.shared.saturday, NotificationTimes.shared.sunday]
|
||||
|
||||
var session: MXSession?
|
||||
|
||||
init(session: MXSession?) {
|
||||
self.session = session
|
||||
if let session = session {
|
||||
RiotSharedSettings(session: session).fetchNotificationTimes()
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 50) {
|
||||
|
||||
NotificationTimesToggle(isOn: $isOn)
|
||||
.padding(.top, 40)
|
||||
|
||||
if isOn {
|
||||
HStack {
|
||||
ForEach(weekdays) { weekday in
|
||||
WeekDayButton(weekday: weekday, selectedDay: $selectedDay)
|
||||
}
|
||||
}
|
||||
|
||||
WeekDaysSettings(weekday: weekdays[selectedDay])
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
.navigationTitle(NSLocalizedString("bwi_notification_times", tableName: "Bwi", comment: ""))
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button(action: updateAccountData) {
|
||||
Text(NSLocalizedString("bwi_notification_times_done_action", tableName: "Bwi", comment: ""))
|
||||
.foregroundColor(Color(ThemeService.shared().theme.tintColor))
|
||||
}
|
||||
}
|
||||
}
|
||||
.onDisappear {
|
||||
updateAccountData()
|
||||
updateSharedUserDefaults()
|
||||
}
|
||||
}
|
||||
|
||||
private func updateAccountData() {
|
||||
if let session = session {
|
||||
_ = RiotSharedSettings(session: session).storeNotificationTimes {
|
||||
print("NotificationTimes successuflly stored to account data")
|
||||
} failure: { error in
|
||||
if let error = error {
|
||||
print("Error: Storing NotificationTimes into account data failed")
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateSharedUserDefaults() {
|
||||
if let data = try? JSONEncoder().encode(NotificationTimes.shared) {
|
||||
let sharedUserDefaults = MXKAppSettings.standard().sharedUserDefaults
|
||||
sharedUserDefaults?.set(data, forKey: NotificationTimes.sharedUserDefaultsKey)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
fileprivate struct NotificationTimesToggle: View {
|
||||
@Binding var isOn: Bool
|
||||
var body: some View {
|
||||
Toggle(isOn: $isOn) {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text(NSLocalizedString("bwi_notification_times_toggle_title", tableName: "Bwi", comment: ""))
|
||||
.font(.headline)
|
||||
.foregroundColor(.primary)
|
||||
Text(NSLocalizedString("bwi_notification_times_toggle_description", tableName: "Bwi", comment: ""))
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: Color(ThemeService.shared().theme.tintColor)))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
fileprivate struct WeekDayButton: View {
|
||||
@ObservedObject var weekday: NotificationTimesWeekday
|
||||
@Binding var selectedDay: Int
|
||||
|
||||
var body: some View {
|
||||
Button(action: { selectedDay = weekday.id }) {
|
||||
ZStack {
|
||||
Group {
|
||||
if weekday.isEnabled {
|
||||
Circle()
|
||||
.foregroundColor(Color(ThemeService.shared().theme.tintColor))
|
||||
} else {
|
||||
Circle()
|
||||
.strokeBorder(Color.secondary, lineWidth: 1)
|
||||
.background(Circle().fill(.clear))
|
||||
}
|
||||
|
||||
Text(weekday.shortName)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.black)
|
||||
}
|
||||
.frame(width: 38, height: 38)
|
||||
|
||||
Circle()
|
||||
.strokeBorder( weekday.id == selectedDay ? .gray : .clear, lineWidth: 2)
|
||||
.frame(width: 45, height: 45)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
fileprivate struct WeekDaysSettings: View {
|
||||
@ObservedObject var weekday: NotificationTimesWeekday
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
UserInfoText(weekdayName: weekday.name, notificationsEnabled: weekday.isEnabled)
|
||||
|
||||
Spacer()
|
||||
.frame(height: 20)
|
||||
|
||||
HStack(spacing: 40) {
|
||||
TimePicker(date: $weekday.startTime, title: NSLocalizedString("bwi_notification_times_start_time", tableName: "Bwi", comment: ""), enabled: weekday.isEnabled)
|
||||
TimePicker(date: $weekday.endTime, title: NSLocalizedString("bwi_notification_times_end_time", tableName: "Bwi", comment: ""), enabled: weekday.isEnabled)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
.frame(height: 50)
|
||||
|
||||
Button(action: { weekday.isEnabled.toggle() }) {
|
||||
if weekday.isEnabled {
|
||||
Text(String(format: NSLocalizedString("bwi_notification_times_button_deactivate", tableName: "Bwi", comment: ""), weekday.name))
|
||||
.foregroundColor(Color(ThemeService.shared().theme.tintColor))
|
||||
} else {
|
||||
Text(String(format: NSLocalizedString("bwi_notification_times_button_activate", tableName: "Bwi", comment: ""), weekday.name))
|
||||
.foregroundColor(Color(ThemeService.shared().theme.tintColor))
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: weekday.startTime) { newValue in
|
||||
if weekday.endTime < newValue {
|
||||
weekday.endTime = newValue
|
||||
}
|
||||
}
|
||||
.onChange(of: weekday.endTime) { newValue in
|
||||
if weekday.startTime > newValue {
|
||||
weekday.startTime = newValue
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
fileprivate struct UserInfoText: View {
|
||||
var weekdayName: String
|
||||
var notificationsEnabled: Bool
|
||||
|
||||
var body: some View {
|
||||
if notificationsEnabled {
|
||||
TwoLineText(String(format: NSLocalizedString("bwi_notification_times_status_activated", tableName: "Bwi", comment: ""), weekdayName), color: notificationsEnabled ? .primary : .secondary)
|
||||
} else {
|
||||
TwoLineText(String(format: NSLocalizedString("bwi_notification_times_status_deactivated", tableName: "Bwi", comment: ""), weekdayName), color: notificationsEnabled ? .primary : .secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
fileprivate struct TimePicker: View {
|
||||
@Binding var date: Date
|
||||
var title: String
|
||||
var enabled: Bool
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Text(title)
|
||||
.foregroundColor(enabled ? .primary : .secondary)
|
||||
ZStack {
|
||||
DatePicker( "", selection: $date, displayedComponents: [.hourAndMinute])
|
||||
.labelsHidden()
|
||||
.opacity(enabled ? 1 : 0)
|
||||
Text("--:--")
|
||||
.foregroundColor(.secondary)
|
||||
.opacity(enabled ? 0 : 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
fileprivate struct TwoLineText: View {
|
||||
var text: String
|
||||
var color: Color
|
||||
|
||||
init(_ text: String, color: Color) {
|
||||
self.text = text
|
||||
self.color = color
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
Text("X\nX")
|
||||
.frame(maxWidth: .infinity)
|
||||
.font(.body)
|
||||
.foregroundColor(.clear)
|
||||
Text(text)
|
||||
.lineLimit(2)
|
||||
.multilineTextAlignment(.center)
|
||||
.font(.body)
|
||||
.foregroundColor(color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
struct NotificationTimesView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
NavigationView {
|
||||
NotificationTimesView(session: nil)
|
||||
.environment(\.locale, Locale.init(identifier: "de"))
|
||||
}
|
||||
}
|
||||
}
|
||||
74
bwi/NotificationTimes/NotificationTimesWeekday.swift
Normal file
74
bwi/NotificationTimes/NotificationTimesWeekday.swift
Normal file
@@ -0,0 +1,74 @@
|
||||
//
|
||||
/*
|
||||
* Copyright (c) 2022 BWI GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
class NotificationTimesWeekday: ObservableObject, Identifiable, Codable {
|
||||
@Published var isEnabled: Bool
|
||||
@Published var name: String
|
||||
@Published var shortName: String
|
||||
@Published var startTime = Date.from(hour: 8, minute: 0)
|
||||
@Published var endTime = Date.from(hour: 17, minute: 0)
|
||||
let id: Int
|
||||
|
||||
private enum CodingKeys : String, CodingKey {
|
||||
case fromHour = "from_hour"
|
||||
case toHour = "to_hour"
|
||||
case fromMinute = "from_minute"
|
||||
case toMinute = "to_minute"
|
||||
case isEnabled = "is_enabled"
|
||||
}
|
||||
|
||||
init(id: Int, name: String, shortName: String, isEnabled: Bool = false) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.shortName = shortName
|
||||
self.isEnabled = isEnabled
|
||||
}
|
||||
|
||||
required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
let fromHour = try container.decode(Int.self, forKey: .fromHour)
|
||||
let toHour = try container.decode(Int.self, forKey: .toHour)
|
||||
let fromMinute = try container.decode(Int.self, forKey: .fromMinute)
|
||||
let toMinute = try container.decode(Int.self, forKey: .toMinute)
|
||||
|
||||
isEnabled = try container.decode(Bool.self, forKey: .toMinute)
|
||||
|
||||
id = 0
|
||||
name = ""
|
||||
shortName = ""
|
||||
startTime = Date.from(hour: fromHour, minute: fromMinute)
|
||||
endTime = Date.from(hour: toHour, minute: toMinute)
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
let calender = Calendar.current
|
||||
let fromHour = calender.component(.hour, from: startTime)
|
||||
let toHour = calender.component(.hour, from: endTime)
|
||||
let fromMinute = calender.component(.minute, from: startTime)
|
||||
let toMinute = calender.component(.minute, from: endTime)
|
||||
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(isEnabled, forKey: .isEnabled)
|
||||
try container.encode(fromHour, forKey: .fromHour)
|
||||
try container.encode(toHour, forKey: .toHour)
|
||||
try container.encode(fromMinute, forKey: .fromMinute)
|
||||
try container.encode(toMinute, forKey: .toMinute)
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 BWI GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
struct WorkTime : Codable {
|
||||
enum Days : Int, CaseIterable, Codable {
|
||||
case sunday = 1
|
||||
case monday = 2
|
||||
case tuesday = 3
|
||||
case wednesday = 4
|
||||
case thursday = 5
|
||||
case friday = 6
|
||||
case saturday = 7
|
||||
case other
|
||||
|
||||
public init!(_ value:RawValue) {
|
||||
guard let validValue = Days(rawValue:value) else {
|
||||
self = .other
|
||||
return
|
||||
}
|
||||
self = validValue
|
||||
}
|
||||
|
||||
static func workdays() -> Set<Days> {
|
||||
Set(Days.allCases.filter { (2...6).contains( $0.rawValue ) })
|
||||
}
|
||||
}
|
||||
|
||||
var workdays : Set<Days>
|
||||
var startTime : Int
|
||||
var finishTime : Int
|
||||
|
||||
init() {
|
||||
workdays = WorkTime.Days.workdays()
|
||||
startTime = 8 * 60
|
||||
finishTime = 17 * 60
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 BWI GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers class WorkTimeModel : NSObject {
|
||||
func formatedWorkTime(_ workTime: WorkTime) -> String {
|
||||
let now = Date()
|
||||
let weekday = Calendar.current.component(.weekday, from: now)
|
||||
|
||||
if workTime.workdays.contains(WorkTime.Days(weekday)) {
|
||||
let startHours = Int(workTime.startTime / 60)
|
||||
let startMinutes = workTime.startTime % 60
|
||||
let finishHours = Int(workTime.finishTime / 60)
|
||||
let finishMinutes = workTime.finishTime % 60
|
||||
|
||||
let startTime = String(format: "%02d:%02d", startHours, startMinutes)
|
||||
let finishTime = String(format: "%02d:%02d", finishHours, finishMinutes)
|
||||
|
||||
if workTime.startTime <= workTime.finishTime {
|
||||
return String(format: NSLocalizedString("room_details_main_section_rest_time_time", tableName: "Vector", comment: ""), startTime, finishTime)
|
||||
} else {
|
||||
return String(format: NSLocalizedString("room_details_main_section_rest_time_time", tableName: "Vector", comment: ""), finishTime, startTime)
|
||||
}
|
||||
|
||||
} else {
|
||||
return NSLocalizedString("room_details_main_section_rest_time_restday", tableName: "Vector", comment: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 BWI GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers class WorkTimeService : NSObject {
|
||||
|
||||
static let minutesInDay = 60 * 24
|
||||
|
||||
var workTime : WorkTime
|
||||
let store : WorkTimeStore
|
||||
|
||||
static func workTimeService(_ userId: String) -> WorkTimeService {
|
||||
let store = WorkTimeStore(userId: userId)
|
||||
return WorkTimeService(store)
|
||||
}
|
||||
|
||||
init(_ store: WorkTimeStore) {
|
||||
self.store = store
|
||||
self.workTime = store.workTime
|
||||
}
|
||||
|
||||
func setStartTime(_ startTime: Int) {
|
||||
var fixedStartTime = startTime
|
||||
|
||||
if fixedStartTime < 0 {
|
||||
fixedStartTime = 0
|
||||
}
|
||||
if fixedStartTime > WorkTimeService.minutesInDay {
|
||||
fixedStartTime = WorkTimeService.minutesInDay
|
||||
}
|
||||
|
||||
self.workTime.startTime = fixedStartTime
|
||||
store.workTime = self.workTime
|
||||
}
|
||||
|
||||
func setFinishTime(_ finishTime: Int) {
|
||||
var fixedFinishTime = finishTime
|
||||
|
||||
if fixedFinishTime > WorkTimeService.minutesInDay {
|
||||
fixedFinishTime = WorkTimeService.minutesInDay
|
||||
}
|
||||
if fixedFinishTime < 0 {
|
||||
fixedFinishTime = 0
|
||||
}
|
||||
|
||||
self.workTime.finishTime = fixedFinishTime
|
||||
store.workTime = self.workTime
|
||||
}
|
||||
|
||||
func addWorkDay(_ day: WorkTime.Days) {
|
||||
self.workTime.workdays.insert(day)
|
||||
store.workTime = self.workTime
|
||||
}
|
||||
|
||||
func removeWorkDay(_ day: WorkTime.Days) {
|
||||
self.workTime.workdays.remove(day)
|
||||
store.workTime = self.workTime
|
||||
}
|
||||
|
||||
func isNowWorkTime() -> Bool {
|
||||
isWorkTime(Date())
|
||||
}
|
||||
|
||||
func isWorkTime(_ date: Date) -> Bool {
|
||||
let weekday = Calendar.current.component(.weekday, from: date)
|
||||
if self.workTime.workdays.contains(WorkTime.Days(weekday)) {
|
||||
let minutes = Calendar.current.component(.hour, from: date)*60 + Calendar.current.component(.minute, from: date)
|
||||
if self.workTime.startTime <= self.workTime.finishTime {
|
||||
if self.workTime.startTime <= minutes && self.workTime.finishTime >= minutes {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if self.workTime.startTime <= minutes || self.workTime.finishTime >= minutes {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isWorkTimeGlobalyEnabled() -> Bool {
|
||||
return store.workTimeEnabled
|
||||
}
|
||||
|
||||
func enableWorkTime(_ enable: Bool) {
|
||||
store.workTimeEnabled = enable
|
||||
}
|
||||
|
||||
func activateWorkTimeInRoom(_ roomId: String) {
|
||||
self.store.activateWorkTimeInRoom(roomId);
|
||||
}
|
||||
|
||||
func deactivateWorkTimeInRoom(_ roomId: String) {
|
||||
self.store.deactivateWorkTimeInRoom(roomId)
|
||||
}
|
||||
|
||||
func localizedWorkTime() -> String {
|
||||
return WorkTimeModel().formatedWorkTime(store.workTime)
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 BWI GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import KeychainAccess
|
||||
|
||||
@objcMembers
|
||||
final class WorkTimeStore : NSObject {
|
||||
|
||||
private enum StoreKeys {
|
||||
static let WorkTimeEnabledKey = "WorkTimeEnabled"
|
||||
static let WorkTimeKey = "WorkTime"
|
||||
static let WorkTimeInRoomsKey = "WorkTimeInRooms"
|
||||
}
|
||||
|
||||
private struct BwiSettingsConstants {
|
||||
static let bwiSettingsKeychainService: String = BuildSettings.baseBundleIdentifier + ".bwi-WorkTime-service"
|
||||
}
|
||||
|
||||
private let vault: KeyValueVault
|
||||
|
||||
private let userId: String
|
||||
|
||||
init(userId : String) {
|
||||
self.userId = userId
|
||||
vault = KeychainVault(Keychain(service: BwiSettingsConstants.bwiSettingsKeychainService,
|
||||
accessGroup: BuildSettings.keychainAccessGroup))
|
||||
super.init()
|
||||
}
|
||||
|
||||
func reset() {
|
||||
do {
|
||||
try vault.removeObject(forKey: StoreKeys.WorkTimeKey)
|
||||
try vault.removeObject(forKey: StoreKeys.WorkTimeEnabledKey)
|
||||
try vault.removeObject(forKey: StoreKeys.WorkTimeInRoomsKey)
|
||||
} catch let error {
|
||||
NSLog("[WorkTime] Error when removing objects: \(error)")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: Servers
|
||||
|
||||
var workTimeEnabled : Bool {
|
||||
get {
|
||||
do {
|
||||
return try vault.bool(forKey: StoreKeys.WorkTimeEnabledKey) ?? false
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
set {
|
||||
do {
|
||||
try vault.set(newValue, forKey: StoreKeys.WorkTimeEnabledKey)
|
||||
} catch let error {
|
||||
NSLog("[WorkTime] Error when storing rest time enabled to the vault: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var workTime : WorkTime {
|
||||
get {
|
||||
do {
|
||||
guard let data = try vault.data(forKey: StoreKeys.WorkTimeKey) else {
|
||||
return WorkTime()
|
||||
}
|
||||
return try JSONDecoder().decode(WorkTimeUser.self, from: data).WorkTime
|
||||
} catch {
|
||||
return WorkTime()
|
||||
}
|
||||
}
|
||||
set {
|
||||
do {
|
||||
let userWorkTime = WorkTimeUser(WorkTime: newValue, userId: userId)
|
||||
let data = try JSONEncoder().encode(userWorkTime)
|
||||
try vault.set(data, forKey: StoreKeys.WorkTimeKey)
|
||||
} catch let error {
|
||||
NSLog("[WorkTime] Error when storing addional header to the vault: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func activateWorkTimeInRoom(_ roomId: String) {
|
||||
let workTimeInRoom = WorkTimeInRoom(userId: userId, roomId: roomId, isWorkTimeActive: true)
|
||||
var roomSet = roomSetFromStore()
|
||||
roomSet.update(with: workTimeInRoom)
|
||||
saveRoomSetToStore(roomSet)
|
||||
}
|
||||
|
||||
func deactivateWorkTimeInRoom(_ roomId: String) {
|
||||
let workTimeInRoom = WorkTimeInRoom(userId: userId, roomId: roomId, isWorkTimeActive: false)
|
||||
var roomSet = roomSetFromStore()
|
||||
roomSet.update(with: workTimeInRoom)
|
||||
saveRoomSetToStore(roomSet)
|
||||
}
|
||||
|
||||
@objc func isWorkTimeRoom(_ roomId: String) -> Bool {
|
||||
let roomSet = roomSetFromStore()
|
||||
if roomSet.first(where: {$0.roomId == roomId && $0.userId == userId}) != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@objc func isWorkTimeInRoomActive(_ roomId: String) -> Bool {
|
||||
let roomSet = roomSetFromStore()
|
||||
|
||||
if let WorkTimeInRoom = roomSet.first(where: {$0.roomId == roomId && $0.userId == userId}) {
|
||||
return WorkTimeInRoom.isWorkTimeActive
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private func roomSetFromStore() -> Set<WorkTimeInRoom> {
|
||||
do {
|
||||
guard let data = try vault.data(forKey: StoreKeys.WorkTimeInRoomsKey) else {
|
||||
return Set<WorkTimeInRoom>()
|
||||
}
|
||||
|
||||
return try JSONDecoder().decode(Set<WorkTimeInRoom>.self, from: data)
|
||||
} catch {
|
||||
return Set<WorkTimeInRoom>()
|
||||
}
|
||||
}
|
||||
|
||||
private func saveRoomSetToStore(_ roomSet: Set<WorkTimeInRoom>) {
|
||||
do {
|
||||
print("saveRoomSetToStore", roomSet)
|
||||
let dataOut = try JSONEncoder().encode(roomSet)
|
||||
try vault.set(dataOut, forKey: StoreKeys.WorkTimeInRoomsKey)
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user