From 3588d9711624399f9c2b2cbd64bb5b4d1794e05e Mon Sep 17 00:00:00 2001 From: QuentinArguillere Date: Tue, 13 Aug 2024 09:52:19 +0200 Subject: [PATCH] Add TimeZone management in meeting scheduling/editing --- .../Meetings/Fragments/MeetingFragment.swift | 2 +- .../Meetings/Fragments/MeetingsFragment.swift | 2 +- .../Fragments/ScheduleMeetingFragment.swift | 26 ++++++++-- .../Meetings/ViewModel/MeetingViewModel.swift | 52 ++++++++++++------- 4 files changed, 56 insertions(+), 26 deletions(-) diff --git a/Linphone/UI/Main/Meetings/Fragments/MeetingFragment.swift b/Linphone/UI/Main/Meetings/Fragments/MeetingFragment.swift index 1b433e480..995cefb12 100644 --- a/Linphone/UI/Main/Meetings/Fragments/MeetingFragment.swift +++ b/Linphone/UI/Main/Meetings/Fragments/MeetingFragment.swift @@ -214,7 +214,7 @@ struct MeetingFragment: View { .foregroundStyle(Color.grayMain2c800) .frame(width: 24, height: 24) .padding(.leading, 15) - Text("TODO : timezone") + Text(meetingViewModel.currentTimeZone.formattedString()) .default_text_style(styleSize: 14) Spacer() } diff --git a/Linphone/UI/Main/Meetings/Fragments/MeetingsFragment.swift b/Linphone/UI/Main/Meetings/Fragments/MeetingsFragment.swift index a5ca04c26..faf2fa9ae 100644 --- a/Linphone/UI/Main/Meetings/Fragments/MeetingsFragment.swift +++ b/Linphone/UI/Main/Meetings/Fragments/MeetingsFragment.swift @@ -66,7 +66,7 @@ struct MeetingsFragment: View { .padding(.top, 5) .default_text_style_500(styleSize: 15) } - Text(model.model!.time) + Text(model.model!.time) // this time string is formatted for the current timezone, we use the selected timezone only when displaying details .default_text_style_500(styleSize: 15) } } diff --git a/Linphone/UI/Main/Meetings/Fragments/ScheduleMeetingFragment.swift b/Linphone/UI/Main/Meetings/Fragments/ScheduleMeetingFragment.swift index 767a6d10a..5f435027e 100644 --- a/Linphone/UI/Main/Meetings/Fragments/ScheduleMeetingFragment.swift +++ b/Linphone/UI/Main/Meetings/Fragments/ScheduleMeetingFragment.swift @@ -192,33 +192,49 @@ struct ScheduleMeetingFragment: View { .foregroundStyle(Color.grayMain2c800) .frame(width: 24, height: 24) .padding(.leading, 15) - Text("TODO : timezone") + Text("Time Zone:") .fontWeight(.bold) - .padding(.leading, 5) .default_text_style_500(styleSize: 16) + Picker(selection: $meetingViewModel.selectedTimezoneIdx, label: EmptyView() ) { + ForEach(0..() var conferenceInfoToEdit: ConferenceInfo? @@ -52,9 +55,21 @@ class MeetingViewModel: ObservableObject { init() { fromDate = Calendar.current.date(byAdding: .hour, value: 1, to: Date.now)! toDate = Calendar.current.date(byAdding: .hour, value: 2, to: Date.now)! + + var tzIds = TimeZone.knownTimeZoneIdentifiers + tzIds.sort(by: { + let gmtOffset0 = TimeZone(identifier: $0)!.secondsFromGMT() + let gmtOffset1 = TimeZone(identifier: $1)!.secondsFromGMT() + if gmtOffset0 == gmtOffset1 { + return $0 < $1 // sort by name if same GMT offset + } else { + return gmtOffset0 < gmtOffset1 + } + }) + knownTimezones = tzIds + selectedTimezoneIdx = knownTimezones.firstIndex(where: {$0 == currentTimeZone.identifier}) ?? 0 computeDateLabels() computeTimeLabels() - updateTimezone() } func resetViewModelData() { @@ -63,7 +78,6 @@ class MeetingViewModel: ObservableObject { subject = "" description = "" allDayMeeting = false - timezone = "" sendInvitations = true participants = [] operationInProgress = false @@ -73,26 +87,32 @@ class MeetingViewModel: ObservableObject { toDate = Calendar.current.date(byAdding: .hour, value: 2, to: Date.now)! computeDateLabels() computeTimeLabels() - updateTimezone() + } + + func updateTimezone(timeZone: TimeZone) { + currentTimeZone = timeZone + computeDateLabels() + computeTimeLabels() } func computeDateLabels() { - var day = fromDate.formatted(Date.FormatStyle().weekday(.wide)) - var dayNumber = fromDate.formatted(Date.FormatStyle().day(.twoDigits)) - var month = fromDate.formatted(Date.FormatStyle().month(.wide)) - fromDateStr = "\(day) \(dayNumber), \(month)" - Log.info("\(MeetingViewModel.TAG) computed start date is \(fromDateStr)") + var weekDayFormat = Date.FormatStyle().weekday(.wide) + weekDayFormat.timeZone = currentTimeZone + var dayNumberFormat = Date.FormatStyle().day(.twoDigits) + dayNumberFormat.timeZone = currentTimeZone + var monthFormat = Date.FormatStyle().month(.wide) + monthFormat.timeZone = currentTimeZone - day = toDate.formatted(Date.FormatStyle().weekday(.wide)) - dayNumber = toDate.formatted(Date.FormatStyle().day(.twoDigits)) - month = toDate.formatted(Date.FormatStyle().month(.wide)) - toDateStr = "\(day) \(dayNumber), \(month)" + fromDateStr = "\(fromDate.formatted(weekDayFormat)) \(fromDate.formatted(dayNumberFormat)), \(fromDate.formatted(monthFormat))" + Log.info("\(MeetingViewModel.TAG) computed start date is \(fromDateStr)") + toDateStr = "\(toDate.formatted(weekDayFormat)) \(toDate.formatted(dayNumberFormat)), \(toDate.formatted(monthFormat))" Log.info("\(MeetingViewModel.TAG)) computed end date is \(toDateStr)") } func computeTimeLabels() { let formatter = DateFormatter() formatter.dateFormat = Locale.current.identifier == "fr_FR" ? "HH:mm" : "h:mm a" + formatter.timeZone = currentTimeZone fromTime = formatter.string(from: fromDate) toTime = formatter.string(from: toDate) } @@ -105,10 +125,6 @@ class MeetingViewModel: ObservableObject { return "\(day). \(dayNumber) \(month) \(year) | \(allDayMeeting ? "All day" : "\(fromTime) - \(toTime)")" } - private func updateTimezone() { - // TODO - } - func addParticipants(participantsToAdd: [SelectedAddressModel]) { var list = participants for selectedAddr in participantsToAdd { @@ -300,7 +316,6 @@ class MeetingViewModel: ObservableObject { self.conferenceUri = meeting.confInfo.uri?.asStringUriOnly() ?? "" self.computeDateLabels() self.computeTimeLabels() - self.updateTimezone() self.displayedMeeting = meeting } } @@ -334,7 +349,6 @@ class MeetingViewModel: ObservableObject { self.isBroadcastSelected = false // TODO FIXME self.computeDateLabels() self.computeTimeLabels() - self.updateTimezone() //self.participants = list }