forked from mirrors/linphone-iphone
Add devices list in Account profile
This commit is contained in:
parent
e383826e91
commit
11053b2ca3
9 changed files with 329 additions and 18 deletions
|
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="#4e6074" viewBox="0 0 256 256"><path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Z"></path></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Z"></path></svg>
|
||||||
|
Before Width: | Height: | Size: 351 B After Width: | Height: | Size: 351 B |
|
|
@ -1 +1 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="#4e6074" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm64-88a8,8,0,0,1-8,8H128a8,8,0,0,1-8-8V72a8,8,0,0,1,16,0v48h48A8,8,0,0,1,192,128Z"></path></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm64-88a8,8,0,0,1-8,8H128a8,8,0,0,1-8-8V72a8,8,0,0,1,16,0v48h48A8,8,0,0,1,192,128Z"></path></svg>
|
||||||
|
Before Width: | Height: | Size: 311 B After Width: | Height: | Size: 311 B |
21
Linphone/Assets.xcassets/desktop.imageset/Contents.json
vendored
Normal file
21
Linphone/Assets.xcassets/desktop.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "desktop.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
1
Linphone/Assets.xcassets/desktop.imageset/desktop.svg
vendored
Normal file
1
Linphone/Assets.xcassets/desktop.imageset/desktop.svg
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M208,40H48A24,24,0,0,0,24,64V176a24,24,0,0,0,24,24h72v16H96a8,8,0,0,0,0,16h64a8,8,0,0,0,0-16H136V200h72a24,24,0,0,0,24-24V64A24,24,0,0,0,208,40ZM48,56H208a8,8,0,0,1,8,8v80H40V64A8,8,0,0,1,48,56ZM208,184H48a8,8,0,0,1-8-8V160H216v16A8,8,0,0,1,208,184Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 373 B |
21
Linphone/Assets.xcassets/device-mobile-camera.imageset/Contents.json
vendored
Normal file
21
Linphone/Assets.xcassets/device-mobile-camera.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "device-mobile-camera.svg",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
1
Linphone/Assets.xcassets/device-mobile-camera.imageset/device-mobile-camera.svg
vendored
Normal file
1
Linphone/Assets.xcassets/device-mobile-camera.imageset/device-mobile-camera.svg
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M176,16H80A24,24,0,0,0,56,40V216a24,24,0,0,0,24,24h96a24,24,0,0,0,24-24V40A24,24,0,0,0,176,16Zm8,200a8,8,0,0,1-8,8H80a8,8,0,0,1-8-8V40a8,8,0,0,1,8-8h96a8,8,0,0,1,8,8ZM140,60a12,12,0,1,1-12-12A12,12,0,0,1,140,60Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 335 B |
|
|
@ -3814,6 +3814,57 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"manage_account_device_last_connection" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Last connection:"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Dernière connexion :"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"manage_account_device_remove" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Remove"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Supprimer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"manage_account_devices_title" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Devices"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Appareils"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"manage_account_dialog_international_prefix_help_message" : {
|
"manage_account_dialog_international_prefix_help_message" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
|
|
@ -3864,6 +3915,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"manage_account_no_device" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "No device found…"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Aucun appareil n'a été trouvé…"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"manage_account_remove_picture" : {
|
"manage_account_remove_picture" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"en" : {
|
"en" : {
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ struct AccountProfileFragment: View {
|
||||||
|
|
||||||
@Binding var isShowAccountProfileFragment: Bool
|
@Binding var isShowAccountProfileFragment: Bool
|
||||||
@State var detailIsOpen: Bool = true
|
@State var detailIsOpen: Bool = true
|
||||||
|
@State var deviceIsOpen: Bool = false
|
||||||
|
|
||||||
@State private var showPhotoPicker = false
|
@State private var showPhotoPicker = false
|
||||||
@State private var selectedImage: UIImage?
|
@State private var selectedImage: UIImage?
|
||||||
|
|
@ -384,7 +385,7 @@ struct AccountProfileFragment: View {
|
||||||
HStack(spacing: 20) {
|
HStack(spacing: 20) {
|
||||||
Toggle("", isOn: Binding(
|
Toggle("", isOn: Binding(
|
||||||
get: { accountModel.isRegistrered },
|
get: { accountModel.isRegistrered },
|
||||||
set: { newValue in
|
set: { _ in
|
||||||
accountProfileViewModel.toggleRegister()
|
accountProfileViewModel.toggleRegister()
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|
@ -408,46 +409,123 @@ struct AccountProfileFragment: View {
|
||||||
.background(.white)
|
.background(.white)
|
||||||
.cornerRadius(15)
|
.cornerRadius(15)
|
||||||
.padding(.all)
|
.padding(.all)
|
||||||
|
.background(Color.gray100)
|
||||||
|
|
||||||
/*
|
|
||||||
HStack(alignment: .center) {
|
HStack(alignment: .center) {
|
||||||
Text("manage_account_details_title")
|
Text("manage_account_devices_title")
|
||||||
.default_text_style_800(styleSize: 18)
|
.default_text_style_800(styleSize: 18)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Image(detailIsOpen ? "caret-up" : "caret-down")
|
Image(deviceIsOpen ? "caret-up" : "caret-down")
|
||||||
.renderingMode(.template)
|
.renderingMode(.template)
|
||||||
.resizable()
|
.resizable()
|
||||||
.foregroundStyle(Color.grayMain2c600)
|
.foregroundStyle(Color.grayMain2c600)
|
||||||
.frame(width: 25, height: 25, alignment: .leading)
|
.frame(width: 25, height: 25, alignment: .leading)
|
||||||
.padding(.all, 10)
|
.padding(.all, 10)
|
||||||
}
|
}
|
||||||
.padding(.top, 10)
|
.padding(.vertical, 10)
|
||||||
.padding(.bottom, 10)
|
|
||||||
.padding(.horizontal, 20)
|
.padding(.horizontal, 20)
|
||||||
.background(Color.gray100)
|
.background(Color.gray100)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
detailIsOpen.toggle()
|
deviceIsOpen.toggle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if detailIsOpen {
|
if deviceIsOpen {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
VStack(spacing: 30) {
|
VStack(spacing: 15) {
|
||||||
Text("manage_account_dialog_international_prefix_help_message")
|
ForEach(accountModel.devices.indices, id: \.self) { index in
|
||||||
.default_text_style_700(styleSize: 15)
|
VStack {
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
HStack {
|
||||||
|
Image(accountModel.devices[index].isMobileDevice ? "device-mobile-camera" : "desktop")
|
||||||
|
.renderingMode(.template)
|
||||||
|
.resizable()
|
||||||
|
.foregroundStyle(Color.grayMain2c600)
|
||||||
|
.frame(width: 25, height: 25, alignment: .leading)
|
||||||
|
|
||||||
|
Text(accountModel.devices[index].deviceName)
|
||||||
|
.default_text_style_700(styleSize: 15)
|
||||||
|
.lineLimit(1)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|
||||||
|
Button(action: {
|
||||||
|
deviceIsOpen = false
|
||||||
|
accountModel.removeDevice(deviceIndex: index)
|
||||||
|
deviceIsOpen = true
|
||||||
|
}, label: {
|
||||||
|
HStack {
|
||||||
|
Image("trash-simple")
|
||||||
|
.renderingMode(.template)
|
||||||
|
.resizable()
|
||||||
|
.foregroundStyle(Color.orangeMain500)
|
||||||
|
.frame(width: 20, height: 20)
|
||||||
|
|
||||||
|
Text("manage_account_device_remove")
|
||||||
|
.default_text_style_orange_500(styleSize: 14)
|
||||||
|
.frame(height: 35)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.padding(.horizontal, 10)
|
||||||
|
.background(Color.orangeMain100)
|
||||||
|
.cornerRadius(60)
|
||||||
|
}
|
||||||
|
.padding(.bottom, 10)
|
||||||
|
|
||||||
|
Text("manage_account_device_last_connection")
|
||||||
|
.default_text_style_700(styleSize: 15)
|
||||||
|
.lineLimit(1)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
Image("calendar-blank")
|
||||||
|
.renderingMode(.template)
|
||||||
|
.resizable()
|
||||||
|
.foregroundStyle(Color.grayMain2c600)
|
||||||
|
.frame(width: 25, height: 25, alignment: .leading)
|
||||||
|
|
||||||
|
Text(accountModel.devices[index].lastDate)
|
||||||
|
.default_text_style(styleSize: 15)
|
||||||
|
.lineLimit(1)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|
||||||
|
Image("clock")
|
||||||
|
.renderingMode(.template)
|
||||||
|
.resizable()
|
||||||
|
.foregroundStyle(Color.grayMain2c600)
|
||||||
|
.frame(width: 25, height: 25, alignment: .leading)
|
||||||
|
|
||||||
|
Text(accountModel.devices[index].lastTime)
|
||||||
|
.default_text_style(styleSize: 15)
|
||||||
|
.lineLimit(1)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.all, 20)
|
||||||
|
.background(Color.gray100)
|
||||||
|
.cornerRadius(15)
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.padding(.vertical, 30)
|
.padding(.all, 20)
|
||||||
.padding(.horizontal, 20)
|
.frame(maxWidth: .infinity)
|
||||||
|
.overlay(
|
||||||
|
VStack {
|
||||||
|
if accountModel.devices.indices.isEmpty {
|
||||||
|
Text("manage_account_no_device")
|
||||||
|
.default_text_style_500(styleSize: 16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.all)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
.background(.white)
|
.background(.white)
|
||||||
.cornerRadius(15)
|
.cornerRadius(15)
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
.zIndex(-1)
|
.zIndex(-2)
|
||||||
.transition(.move(edge: .top))
|
.transition(.move(edge: .top))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -463,9 +541,11 @@ struct AccountProfileFragment: View {
|
||||||
.background(.white)
|
.background(.white)
|
||||||
.cornerRadius(15)
|
.cornerRadius(15)
|
||||||
.padding(.all)
|
.padding(.all)
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
.frame(maxWidth: sharedMainViewModel.maxWidth)
|
.frame(maxWidth: sharedMainViewModel.maxWidth)
|
||||||
|
.onAppear {
|
||||||
|
accountModel.requestDevicesList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ import SwiftUI
|
||||||
import Combine
|
import Combine
|
||||||
|
|
||||||
class AccountModel: ObservableObject {
|
class AccountModel: ObservableObject {
|
||||||
|
static let TAG = "[AccountModel]"
|
||||||
|
|
||||||
let account: Account
|
let account: Account
|
||||||
@Published var humanReadableRegistrationState: String = ""
|
@Published var humanReadableRegistrationState: String = ""
|
||||||
@Published var summary: String = ""
|
@Published var summary: String = ""
|
||||||
|
|
@ -38,9 +40,14 @@ class AccountModel: ObservableObject {
|
||||||
@Published var usernaneAvatar: String = ""
|
@Published var usernaneAvatar: String = ""
|
||||||
@Published var imagePathAvatar: URL?
|
@Published var imagePathAvatar: URL?
|
||||||
|
|
||||||
|
@Published var devices: [AccountDeviceModel] = []
|
||||||
|
|
||||||
private var accountDelegate: AccountDelegate?
|
private var accountDelegate: AccountDelegate?
|
||||||
private var coreDelegate: CoreDelegate?
|
private var coreDelegate: CoreDelegate?
|
||||||
|
|
||||||
|
private var accountManagerServices: AccountManagerServices?
|
||||||
|
private var requestDelegate: AccountManagerServicesRequestDelegate?
|
||||||
|
|
||||||
init(account: Account, core: Core) {
|
init(account: Account, core: Core) {
|
||||||
self.account = account
|
self.account = account
|
||||||
|
|
||||||
|
|
@ -83,6 +90,8 @@ class AccountModel: ObservableObject {
|
||||||
let displayName = account.displayName()
|
let displayName = account.displayName()
|
||||||
let address = account.params?.identityAddress?.asString()
|
let address = account.params?.identityAddress?.asString()
|
||||||
|
|
||||||
|
self.requestDevicesList()
|
||||||
|
|
||||||
let displayNameTmp = account.params?.identityAddress?.displayName ?? ""
|
let displayNameTmp = account.params?.identityAddress?.displayName ?? ""
|
||||||
let usernaneAvatarTmp = account.contactAddress?.username ?? ""
|
let usernaneAvatarTmp = account.contactAddress?.username ?? ""
|
||||||
var photoAvatarModelTmp = ""
|
var photoAvatarModelTmp = ""
|
||||||
|
|
@ -153,4 +162,114 @@ class AccountModel: ObservableObject {
|
||||||
|
|
||||||
return imagePath
|
return imagePath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func requestDevicesList() {
|
||||||
|
if account.params != nil && account.params!.identityAddress != nil, let identityAddress = account.params!.identityAddress {
|
||||||
|
Log.info(
|
||||||
|
"\(AccountModel.TAG) Request devices list for identity address \(identityAddress.asStringUriOnly())"
|
||||||
|
)
|
||||||
|
CoreContext.shared.doOnCoreQueue { core in
|
||||||
|
do {
|
||||||
|
self.accountManagerServices = try core.createAccountManagerServices()
|
||||||
|
if self.accountManagerServices != nil {
|
||||||
|
self.accountManagerServices!.language = Locale.current.identifier
|
||||||
|
|
||||||
|
do {
|
||||||
|
let request = try self.accountManagerServices!.createGetDevicesListRequest(sipIdentity: identityAddress)
|
||||||
|
self.addDelegate(request: request)
|
||||||
|
} catch {
|
||||||
|
print("\(AccountModel.TAG) Failed to create request: \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addDelegate(request: AccountManagerServicesRequest) {
|
||||||
|
self.requestDelegate = AccountManagerServicesRequestDelegateStub(
|
||||||
|
onRequestSuccessful: { (request: AccountManagerServicesRequest, data: String) in
|
||||||
|
Log.info("\(AccountModel.TAG) Request \(request) was successful, data is \(data)")
|
||||||
|
}, onRequestError: { (request: AccountManagerServicesRequest, statusCode: Int, errorMessage: String, parameterErrors: Dictionary?) in
|
||||||
|
Log.error(
|
||||||
|
"\(AccountModel.TAG) Request \(request) returned an error with status code \(statusCode) and message \(errorMessage)"
|
||||||
|
)
|
||||||
|
// TODO Display Error Toast
|
||||||
|
}, onDevicesListFetched: { (request: AccountManagerServicesRequest, accountDevices: [AccountDevice]) in
|
||||||
|
Log.info("\(AccountModel.TAG) Fetched \(accountDevices.count) devices for our account")
|
||||||
|
var devicesList: [AccountDeviceModel] = []
|
||||||
|
accountDevices.forEach { accountDevice in
|
||||||
|
devicesList.append(AccountDeviceModel(accountDevice: accountDevice))
|
||||||
|
}
|
||||||
|
|
||||||
|
request.removeDelegate(delegate: self.requestDelegate!)
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.devices = devicesList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
request.addDelegate(delegate: self.requestDelegate!)
|
||||||
|
request.submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeDevice(deviceIndex: Int) {
|
||||||
|
let removedDevice = self.devices[deviceIndex].accountDevice
|
||||||
|
self.devices.remove(at: deviceIndex)
|
||||||
|
if account.params != nil && account.params!.identityAddress != nil, let identityAddress = account.params!.identityAddress {
|
||||||
|
Log.info(
|
||||||
|
"\(AccountModel.TAG) Delete device for identity address \(identityAddress.asStringUriOnly())"
|
||||||
|
)
|
||||||
|
CoreContext.shared.doOnCoreQueue { core in
|
||||||
|
do {
|
||||||
|
self.accountManagerServices = try core.createAccountManagerServices()
|
||||||
|
if self.accountManagerServices != nil {
|
||||||
|
self.accountManagerServices!.language = Locale.current.identifier
|
||||||
|
|
||||||
|
do {
|
||||||
|
let request = try self.accountManagerServices!.createDeleteDeviceRequest(sipIdentity: identityAddress, device: removedDevice)
|
||||||
|
self.addDelegate(request: request)
|
||||||
|
} catch {
|
||||||
|
print("\(AccountModel.TAG) Failed to create request: \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AccountDeviceModel: ObservableObject {
|
||||||
|
let accountDevice: AccountDevice
|
||||||
|
@Published var deviceName: String = ""
|
||||||
|
@Published var lastDate: String = ""
|
||||||
|
@Published var lastTime: String = ""
|
||||||
|
@Published var isMobileDevice: Bool = true
|
||||||
|
|
||||||
|
init(accountDevice: AccountDevice) {
|
||||||
|
self.accountDevice = accountDevice
|
||||||
|
self.deviceName = accountDevice.name ?? ""
|
||||||
|
|
||||||
|
let timeInterval = TimeInterval(accountDevice.lastUpdateTimestamp ?? 0)
|
||||||
|
let dateTmp = Date(timeIntervalSince1970: timeInterval)
|
||||||
|
|
||||||
|
let dateFormat = DateFormatter()
|
||||||
|
dateFormat.dateFormat = Locale.current.identifier == "fr_FR" ? "dd/MM/YYYY" : "MM/dd/YYYY"
|
||||||
|
let date = dateFormat.string(from: dateTmp)
|
||||||
|
|
||||||
|
let dateFormatBis = DateFormatter()
|
||||||
|
dateFormatBis.dateFormat = "HH:mm"
|
||||||
|
let time = dateFormatBis.string(from: dateTmp)
|
||||||
|
|
||||||
|
self.lastDate = date
|
||||||
|
self.lastTime = time
|
||||||
|
|
||||||
|
self.isMobileDevice = accountDevice.userAgent.contains("LinphoneAndroid") || accountDevice.userAgent.contains(
|
||||||
|
"LinphoneiOS"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue