Add settings to show past meetings and limit max width in settings views

This commit is contained in:
Benoit Martins 2026-03-16 13:53:00 +01:00
parent 2f56839937
commit c01f79dd20
16 changed files with 125 additions and 63 deletions

View file

@ -20,7 +20,7 @@
import Foundation
import linphonesw
class CorePreferences {
class CorePreferences: ObservableObject {
private let config: Config
@ -357,6 +357,18 @@ class CorePreferences {
}
}
var showPastMeetings: Bool {
get {
config.getBool(section: "ui", key: "show_past_meetings", defaultValue: true)
}
set {
DispatchQueue.main.async {
self.objectWillChange.send()
}
config.setBool(section: "ui", key: "show_past_meetings", value: newValue)
}
}
var singleSignOnClientId: String {
get {
config.getString(section: "app", key: "oidc_client_id", defaultString: "linphone")

View file

@ -1,7 +1,7 @@
import Foundation
public enum AppGitInfo {
public static let branch = "feature/update_settings"
public static let commit = "5906c3449"
public static let branch = "master"
public static let commit = "65e685101"
public static let tag = "6.1.0-alpha"
}

View file

@ -562,6 +562,7 @@
"settings_meetings_layout_active_speaker_label" = "Active speaker";
"settings_meetings_layout_mosaic_label" = "Mosaic";
"settings_meetings_title" = "Meetings";
"settings_meetings_show_past_meetings_title" = "Show past meetings";
"settings_network_allow_ipv6" = "Allow IPv6";
"settings_network_title" = "Network";
"settings_network_use_wifi_only" = "Use only Wi-Fi networks";

View file

@ -562,6 +562,7 @@
"settings_meetings_layout_active_speaker_label" = "Intervenant actif";
"settings_meetings_layout_mosaic_label" = "Mosaïque";
"settings_meetings_title" = "Réunions";
"settings_meetings_show_past_meetings_title" = "Afficher les réunions passées";
"settings_network_allow_ipv6" = "Autoriser l'IPv6";
"settings_network_title" = "Réseau";
"settings_network_use_wifi_only" = "Se connecter uniquement via le Wi-Fi";

View file

@ -459,6 +459,11 @@ struct ContentView: View {
sharedMainViewModel.displayedFriend = nil
sharedMainViewModel.displayedCall = nil
sharedMainViewModel.displayedConversation = nil
if let meetingsListVM = meetingsListViewModel, sharedMainViewModel.indexView == 3 {
meetingsListVM.currentFilter = ""
meetingsListVM.computeMeetingsList()
}
}, label: {
VStack {
Image("video-conference")
@ -1096,6 +1101,11 @@ struct ContentView: View {
sharedMainViewModel.displayedFriend = nil
sharedMainViewModel.displayedCall = nil
sharedMainViewModel.displayedConversation = nil
if let meetingsListVM = meetingsListViewModel, sharedMainViewModel.indexView == 3 {
meetingsListVM.currentFilter = ""
meetingsListVM.computeMeetingsList()
}
}, label: {
VStack {
Image("video-conference")

View file

@ -24,6 +24,8 @@ struct MeetingsFragment: View {
@EnvironmentObject var meetingsListViewModel: MeetingsListViewModel
@ObservedObject var corePreferences = AppServices.corePreferences
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@Binding var showingSheet: Bool
@ -186,6 +188,9 @@ struct MeetingsFragment: View {
.navigationTitle("")
.navigationBarHidden(true)
}
.onChange(of: corePreferences.showPastMeetings) { _ in
meetingsListViewModel.computeMeetingsList()
}
}
}

View file

@ -27,6 +27,7 @@ class MeetingModel: ObservableObject {
var meetingDate: Date
var endDate: Date
var isToday: Bool
var isInPast: Bool
var isAfterToday: Bool
private let startTime: String
@ -55,6 +56,7 @@ class MeetingModel: ObservableObject {
dayNumber = meetingDate.formatted(Date.FormatStyle().day(.twoDigits))
isToday = Calendar.current.isDateInToday(meetingDate)
isInPast = meetingDate < Date.now
if isToday {
isAfterToday = false
} else {

View file

@ -98,7 +98,7 @@ class MeetingsListViewModel: ObservableObject {
}
}
if matchFilter {
if matchFilter && (AppServices.corePreferences.showPastMeetings || !model.isInPast) {
meetingsListTmp.append(MeetingsListItemModel(meetingModel: model))
currentIdx += 1
}

View file

@ -213,10 +213,16 @@ struct CardDavAddressBookConfigurationFragment: View {
.default_text_style_700(styleSize: 15)
}
.padding(.vertical, 30)
.padding(.vertical, 20)
.padding(.horizontal, 20)
.background(.white)
.cornerRadius(15)
.background(Color.gray100)
}
.padding(.vertical, 20)
.padding(.horizontal, 20)
.frame(maxWidth: SharedMainViewModel.shared.maxWidth)
.frame(maxWidth: .infinity)
}
.background(Color.gray100)
}

View file

@ -359,10 +359,16 @@ struct LdapServerConfigurationFragment: View {
.focused($isSipDomainFocused)
}
}
.padding(.vertical, 30)
.padding(.vertical, 20)
.padding(.horizontal, 20)
.background(.white)
.cornerRadius(15)
.background(Color.gray100)
}
.padding(.vertical, 20)
.padding(.horizontal, 20)
.frame(maxWidth: SharedMainViewModel.shared.maxWidth)
.frame(maxWidth: .infinity)
}
.background(Color.gray100)
}

View file

@ -263,6 +263,8 @@ struct SettingsAdvancedCallFragment: View {
}
}
.background(Color.gray100)
.frame(maxWidth: SharedMainViewModel.shared.maxWidth)
.frame(maxWidth: .infinity)
}
.background(Color.gray100)
}

View file

@ -241,6 +241,8 @@ struct SettingsAdvancedFragment: View {
}
.padding(.vertical, 20)
.padding(.horizontal, 20)
.frame(maxWidth: SharedMainViewModel.shared.maxWidth)
.frame(maxWidth: .infinity)
}
.background(Color.gray100)
}

View file

@ -185,6 +185,8 @@ struct SettingsDeveloperFragment: View {
}
.padding(.vertical, 20)
.padding(.horizontal, 20)
.frame(maxWidth: SharedMainViewModel.shared.maxWidth)
.frame(maxWidth: .infinity)
}
.background(Color.gray100)
}

View file

@ -427,6 +427,9 @@ struct SettingsFragment: View {
if meetingsIsOpen {
VStack(spacing: 0) {
VStack(spacing: 30) {
Toggle("settings_meetings_show_past_meetings_title", isOn: $settingsViewModel.showPastMeetings)
.default_text_style_700(styleSize: 15)
VStack(alignment: .leading) {
Text("settings_meetings_default_layout_title")
.default_text_style_700(styleSize: 15)
@ -607,6 +610,8 @@ struct SettingsFragment: View {
.background(Color.gray100)
}
}
.frame(maxWidth: SharedMainViewModel.shared.maxWidth)
.frame(maxWidth: .infinity)
}
.background(Color.gray100)
}

View file

@ -31,11 +31,11 @@ class CardDavViewModel: ObservableObject {
let tempRemoteAddressBookFriendList = "TempRemoteDirectoryContacts address-book"
@Published var isEdit: Bool = false
@Published var displayName: String = "CardDav Test"
@Published var serverUrl: String = "https://dav.berfini.me/dav.php/addressbooks/BC/default/"
@Published var username: String = "BC"
@Published var password: String = "cotcot"
@Published var realm: String = "BaikalDAV"
@Published var displayName: String = ""
@Published var serverUrl: String = ""
@Published var username: String = ""
@Published var password: String = ""
@Published var realm: String = ""
@Published var storeNewContactsInIt: Bool = false
@Published var isReadOnly: Bool = false

View file

@ -45,6 +45,7 @@ class SettingsViewModel: ObservableObject {
// Meetings settings
@Published var defaultLayout: String = ""
@Published var showPastMeetings: Bool = false
// Network settings
@Published var useWifiOnly: Bool = false
@ -90,6 +91,7 @@ class SettingsViewModel: ObservableObject {
let hideNotificationContentTmp = !AppServices.corePreferences.showChatMessageContentInNotification
let defaultLayoutTmp = core.defaultConferenceLayout.rawValue == 0 ? String(localized: "settings_meetings_layout_mosaic_label") : String(localized: "settings_meetings_layout_active_speaker_label")
let showPastMeetingsTmp = AppServices.corePreferences.showPastMeetings
let useWifiOnlyTmp = core.wifiOnlyEnabled
let allowIpv6Tmp = core.ipv6Enabled
@ -130,6 +132,7 @@ class SettingsViewModel: ObservableObject {
self.hideNotificationContent = hideNotificationContentTmp
self.defaultLayout = defaultLayoutTmp
self.showPastMeetings = showPastMeetingsTmp
self.useWifiOnly = useWifiOnlyTmp
self.allowIpv6 = allowIpv6Tmp
@ -359,6 +362,59 @@ class SettingsViewModel: ObservableObject {
}
}
func clearNativeFriendsDatabase() {
CoreContext.shared.doOnCoreQueue { core in
let nativeAddressBookFriendList = "Native address-book"
if let list = core.getFriendListByName(name: nativeAddressBookFriendList) {
let friends = list.friends
Log.info("\(SettingsViewModel.TAG) Friend list to remove found with \(friends.count) friends")
for friend in friends {
_ = list.removeFriend(linphoneFriend: friend)
}
core.removeFriendList(list: list)
Log.info("\(SettingsViewModel.TAG) Friend list \(nativeAddressBookFriendList) removed")
}
DispatchQueue.main.async {
ToastViewModel.shared.show("Success_cleared_native_friends_toast")
}
}
}
func clearOrphanAuthInfo() {
CoreContext.shared.doOnCoreQueue { core in
var count = 0
for authInfo in core.authInfoList {
if let username = authInfo.username {
let account = core.accountList.first {
$0.params?.identityAddress?.username == username
}
if account == nil {
Log.info("\(SettingsViewModel.TAG) Removing auth info \(authInfo) with username \(username) for which no account was found")
core.removeAuthInfo(info: authInfo)
count += 1
}
} else {
Log.info("\(SettingsViewModel.TAG) Removing auth info \(authInfo) without username")
core.removeAuthInfo(info: authInfo)
count += 1
}
}
if count == 0 {
DispatchQueue.main.async {
ToastViewModel.shared.show("Success_no_auth_info_removed_toast")
}
} else {
DispatchQueue.main.async {
ToastViewModel.shared.show("Success_cleared_auth_info_toast")
}
}
}
}
func saveChangesWhenLeaving() {
CoreContext.shared.doOnCoreQueue { core in
if AppServices.corePreferences.vfsEnabled != self.enableVfs {
@ -390,6 +446,10 @@ class SettingsViewModel: ObservableObject {
core.defaultConferenceLayout = self.defaultLayout == String(localized: "settings_meetings_layout_mosaic_label") ? .Grid : .ActiveSpeaker
}
if AppServices.corePreferences.showPastMeetings != self.showPastMeetings {
AppServices.corePreferences.showPastMeetings = self.showPastMeetings
}
if core.wifiOnlyEnabled != self.useWifiOnly {
core.wifiOnlyEnabled = self.useWifiOnly
}
@ -455,56 +515,4 @@ class SettingsViewModel: ObservableObject {
}
}
}
func clearNativeFriendsDatabase() {
CoreContext.shared.doOnCoreQueue { core in
let nativeAddressBookFriendList = "Native address-book"
if let list = core.getFriendListByName(name: nativeAddressBookFriendList) {
let friends = list.friends
Log.info("\(SettingsViewModel.TAG) Friend list to remove found with \(friends.count) friends")
for friend in friends {
_ = list.removeFriend(linphoneFriend: friend)
}
core.removeFriendList(list: list)
Log.info("\(SettingsViewModel.TAG) Friend list \(nativeAddressBookFriendList) removed")
}
DispatchQueue.main.async {
ToastViewModel.shared.show("Success_cleared_native_friends_toast")
}
}
}
func clearOrphanAuthInfo() {
CoreContext.shared.doOnCoreQueue { core in
var count = 0
for authInfo in core.authInfoList {
if let username = authInfo.username {
let account = core.accountList.first {
$0.params?.identityAddress?.username == username
}
if account == nil {
Log.info("\(SettingsViewModel.TAG) Removing auth info \(authInfo) with username \(username) for which no account was found")
core.removeAuthInfo(info: authInfo)
count += 1
}
} else {
Log.info("\(SettingsViewModel.TAG) Removing auth info \(authInfo) without username")
core.removeAuthInfo(info: authInfo)
count += 1
}
}
if count == 0 {
DispatchQueue.main.async {
ToastViewModel.shared.show("Success_no_auth_info_removed_toast")
}
} else {
DispatchQueue.main.async {
ToastViewModel.shared.show("Success_cleared_auth_info_toast")
}
}
}
}
}