diff --git a/Linphone.xcodeproj/project.pbxproj b/Linphone.xcodeproj/project.pbxproj index 53cd58f77..b287e6ada 100644 --- a/Linphone.xcodeproj/project.pbxproj +++ b/Linphone.xcodeproj/project.pbxproj @@ -9,6 +9,10 @@ /* Begin PBXBuildFile section */ 660AAF7F2B839272004C0FA6 /* msgNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 660AAF7B2B839271004C0FA6 /* msgNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 660D8A712B517D260092694D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 660D8A702B517D260092694D /* GoogleService-Info.plist */; }; + 6613A0AE2BAEB7DF008923A4 /* MeetingFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A0AD2BAEB7DF008923A4 /* MeetingFragment.swift */; }; + 6613A0B02BAEB7F4008923A4 /* MeetingsListFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A0AF2BAEB7F4008923A4 /* MeetingsListFragment.swift */; }; + 6613A0B42BAEBE3F008923A4 /* MeetingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A0B32BAEBE3F008923A4 /* MeetingViewModel.swift */; }; + 6613A0B62BAEBE5C008923A4 /* ScheduleMeetingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6613A0B52BAEBE5C008923A4 /* ScheduleMeetingViewModel.swift */; }; 662B69D92B25DE18007118BF /* TelecomManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662B69D82B25DE18007118BF /* TelecomManager.swift */; }; 662B69DB2B25DE25007118BF /* ProviderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662B69DA2B25DE25007118BF /* ProviderDelegate.swift */; }; 667E5D7F2B8E430C00EBCFC4 /* linphonerc-factory in Resources */ = {isa = PBXBuildFile; fileRef = D732A90B2B0376F500DB42BA /* linphonerc-factory */; }; @@ -22,7 +26,6 @@ 66E56BC92BA4A6D7006CE56F /* MeetingsListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66E56BC82BA4A6D7006CE56F /* MeetingsListViewModel.swift */; }; 66E56BCC2BA9A1E0006CE56F /* MeetingsListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66E56BCB2BA9A1E0006CE56F /* MeetingsListItemModel.swift */; }; 66E56BCE2BA9A1F8006CE56F /* MeetingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66E56BCD2BA9A1F8006CE56F /* MeetingModel.swift */; }; - 66E56BD22BA9A25B006CE56F /* MeetingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66E56BD12BA9A25B006CE56F /* MeetingViewModel.swift */; }; 66FBFC482B83B8CC00BC6AB1 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C492002B24DB6900CEA16D /* Log.swift */; }; 66FBFC492B83BD2400BC6AB1 /* ConfigExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491F82B24D25A00CEA16D /* ConfigExtension.swift */; }; 66FBFC4A2B83BD3300BC6AB1 /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FE2B24D4AC00CEA16D /* FileUtils.swift */; }; @@ -155,6 +158,10 @@ 660AAF7B2B839271004C0FA6 /* msgNotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = msgNotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 660AAF842B8392E0004C0FA6 /* msgNotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = msgNotificationService.entitlements; sourceTree = ""; }; 660D8A702B517D260092694D /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 6613A0AD2BAEB7DF008923A4 /* MeetingFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingFragment.swift; sourceTree = ""; }; + 6613A0AF2BAEB7F4008923A4 /* MeetingsListFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingsListFragment.swift; sourceTree = ""; }; + 6613A0B32BAEBE3F008923A4 /* MeetingViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeetingViewModel.swift; sourceTree = ""; }; + 6613A0B52BAEBE5C008923A4 /* ScheduleMeetingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScheduleMeetingViewModel.swift; sourceTree = ""; }; 662B69D82B25DE18007118BF /* TelecomManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelecomManager.swift; sourceTree = ""; }; 662B69DA2B25DE25007118BF /* ProviderDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProviderDelegate.swift; sourceTree = ""; }; 667E5D802B8E444D00EBCFC4 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; @@ -167,7 +174,6 @@ 66E56BC82BA4A6D7006CE56F /* MeetingsListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingsListViewModel.swift; sourceTree = ""; }; 66E56BCB2BA9A1E0006CE56F /* MeetingsListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingsListItemModel.swift; sourceTree = ""; }; 66E56BCD2BA9A1F8006CE56F /* MeetingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingModel.swift; sourceTree = ""; }; - 66E56BD12BA9A25B006CE56F /* MeetingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingViewModel.swift; sourceTree = ""; }; D706BA812ADD72D100278F45 /* DeviceRotationViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceRotationViewModifier.swift; sourceTree = ""; }; D70959F02B8DF3EC0014AC0B /* ConversationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationModel.swift; sourceTree = ""; }; D70A26ED2B7CF60B006CC8FC /* ConversationsListBottomSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationsListBottomSheet.swift; sourceTree = ""; }; @@ -333,6 +339,8 @@ 66E56BC62BA49938006CE56F /* Fragments */ = { isa = PBXGroup; children = ( + 6613A0AD2BAEB7DF008923A4 /* MeetingFragment.swift */, + 6613A0AF2BAEB7F4008923A4 /* MeetingsListFragment.swift */, ); path = Fragments; sourceTree = ""; @@ -341,7 +349,8 @@ isa = PBXGroup; children = ( 66E56BC82BA4A6D7006CE56F /* MeetingsListViewModel.swift */, - 66E56BD12BA9A25B006CE56F /* MeetingViewModel.swift */, + 6613A0B32BAEBE3F008923A4 /* MeetingViewModel.swift */, + 6613A0B52BAEBE5C008923A4 /* ScheduleMeetingViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -938,6 +947,7 @@ D7F4D9CB2B5FD27200CDCD76 /* CallsListFragment.swift in Sources */, D72992392ADD7F68003AF125 /* HistoryContactFragment.swift in Sources */, D70A26F02B7D02E6006CC8FC /* ConversationViewModel.swift in Sources */, + 6613A0AE2BAEB7DF008923A4 /* MeetingFragment.swift in Sources */, D7B5066D2AEFA9B900CEB4E9 /* ContactInnerFragment.swift in Sources */, D7E6D04D2AEBD77600A57AAF /* CustomBottomSheet.swift in Sources */, D73449992BC6932A00778C56 /* MeetingWaitingRoomFragment.swift in Sources */, @@ -955,6 +965,7 @@ D72250632ADE9615008FB426 /* HistoryViewModel.swift in Sources */, 66E56BC92BA4A6D7006CE56F /* MeetingsListViewModel.swift in Sources */, D726E4392B16440C0083C415 /* ContactAvatarModel.swift in Sources */, + 6613A0B02BAEB7F4008923A4 /* MeetingsListFragment.swift in Sources */, D76005F62B0798B00054B79A /* IntExtension.swift in Sources */, D7E6D0512AEBDBD500A57AAF /* ContactsListBottomSheet.swift in Sources */, D75759322B56D40900E7AC10 /* ZRTPPopup.swift in Sources */, @@ -963,9 +974,10 @@ D7E6ADF52B9876ED0009A2BC /* Attachment.swift in Sources */, D7A03FC02ACC2E390081A588 /* HistoryView.swift in Sources */, D748BF2E2ACD82E7004844EB /* ThirdPartySipAccountWarningFragment.swift in Sources */, + 6613A0B42BAEBE3F008923A4 /* MeetingViewModel.swift in Sources */, D7173EBE2B7A5C0A00BCC481 /* LinphoneUtils.swift in Sources */, 66C492012B24DB6900CEA16D /* Log.swift in Sources */, - 66E56BD22BA9A25B006CE56F /* MeetingViewModel.swift in Sources */, + 6613A0B62BAEBE5C008923A4 /* ScheduleMeetingViewModel.swift in Sources */, D748BF2C2ACD82D2004844EB /* ThirdPartySipAccountLoginFragment.swift in Sources */, D7CEE0382B7A214F00FD79B7 /* ConversationsListViewModel.swift in Sources */, D74C9CF82ACACECE0021626A /* WelcomePage1Fragment.swift in Sources */, diff --git a/Linphone/UI/Main/Meetings/Fragments/MeetingFragment.swift b/Linphone/UI/Main/Meetings/Fragments/MeetingFragment.swift new file mode 100644 index 000000000..cce87d668 --- /dev/null +++ b/Linphone/UI/Main/Meetings/Fragments/MeetingFragment.swift @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import SwiftUI + +struct MeetingFragment: View { + + @ObservedObject var meetingViewModel: MeetingViewModel + + var body: some View { + ZStack { + Text("TODO") + } + } +} + +#Preview { + MeetingFragment(meetingViewModel: MeetingViewModel()) +} diff --git a/Linphone/UI/Main/Meetings/Fragments/MeetingsListFragment.swift b/Linphone/UI/Main/Meetings/Fragments/MeetingsListFragment.swift new file mode 100644 index 000000000..c9e6a473e --- /dev/null +++ b/Linphone/UI/Main/Meetings/Fragments/MeetingsListFragment.swift @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// swiftlint:disable line_length + +import SwiftUI +import linphonesw + +struct MeetingsListFragment: View { + + @ObservedObject var meetingsListViewModel: MeetingsListViewModel + + @Binding var showingSheet: Bool + + var body: some View { + VStack { + + } + } +} + +#Preview { + MeetingsListFragment(meetingsListViewModel: MeetingsListViewModel(), showingSheet: .constant(false)) +} + +// swiftlint:enable line_length diff --git a/Linphone/UI/Main/Meetings/Models/MeetingModel.swift b/Linphone/UI/Main/Meetings/Models/MeetingModel.swift index 1632709de..a6c797916 100644 --- a/Linphone/UI/Main/Meetings/Models/MeetingModel.swift +++ b/Linphone/UI/Main/Meetings/Models/MeetingModel.swift @@ -34,7 +34,7 @@ class MeetingModel: ObservableObject { let formatter = DateFormatter() formatter.dateFormat = Locale.current.identifier == "fr_FR" ? "HH:mm" : "h:mm a" startTime = formatter.string(from: meetingDate) - let endDate = meetingDate + Double(confInfo.duration * 60) // confInfo.duration is in minutes + let endDate = Calendar.current.date(byAdding: .minute, value: Int(confInfo.duration), to: meetingDate) endTime = formatter.string(from: endDate) time = "\(startTime) - \(endTime)" diff --git a/Linphone/UI/Main/Meetings/ViewModel/MeetingViewModel.swift b/Linphone/UI/Main/Meetings/ViewModel/MeetingViewModel.swift index 9ae230c9f..9afe0ac22 100644 --- a/Linphone/UI/Main/Meetings/ViewModel/MeetingViewModel.swift +++ b/Linphone/UI/Main/Meetings/ViewModel/MeetingViewModel.swift @@ -1,8 +1,24 @@ -// -// MeetingViewModel.swift -// Linphone -// -// Created by QuentinArguillere on 19/03/2024. -// +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ import Foundation + +class MeetingViewModel: ObservableObject { + +} diff --git a/Linphone/UI/Main/Meetings/ViewModel/ScheduleMeetingViewModel.swift b/Linphone/UI/Main/Meetings/ViewModel/ScheduleMeetingViewModel.swift new file mode 100644 index 000000000..9c42bc6ef --- /dev/null +++ b/Linphone/UI/Main/Meetings/ViewModel/ScheduleMeetingViewModel.swift @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import Foundation +import linphonesw +import Combine + + +class ScheduleMeetingViewModel: ObservableObject { + private let TAG = "[ScheduleMeetingViewModel]" + + @Published var isBroadcastSelected: Bool + @Published var showBroadcastHelp: Bool + @Published var subject: String + @Published var description: String + @Published var allDayMeeting: Bool + @Published var fromDateStr: String + @Published var fromTime: String + @Published var toDateStr: String + @Published var toTime: String + @Published var timezone: String + @Published var sendInvitations: Bool + // var participants = MutableLiveData>() + @Published var operationInProgress: Bool + @Published var conferenceCreatedEvent: Bool + + var conferenceScheduler: ConferenceScheduler? + var conferenceInfoToEdit: ConferenceScheduler? + + private var fromDate: Date + private var toDate: Date + + init() { + isBroadcastSelected = false + showBroadcastHelp = false + allDayMeeting = false + sendInvitations = true + + fromDate = Calendar.current.date(byAdding: .hour, value: 1, to: Date.now)! + toDate = Calendar.current.date(byAdding: .hour, value: 1, to: fromDate)! + + computeDateLabels() + computeTimeLabels() + updateTimezone() + } + + private 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("\(TAG) computed start date is \(fromDateStr)") + + 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)" + Log.info("\(TAG) computed end date is \(toDateStr)") + } + + private func computeTimeLabels() { + let formatter = DateFormatter() + formatter.dateFormat = Locale.current.identifier == "fr_FR" ? "HH:mm" : "h:mm a" + fromTime = formatter.string(from: fromDate) + toTime = formatter.string(from:toDate) + } + + private func updateTimezone() { + // TODO + } +} +