blob: 08649fd80d07363a8851b28d3d69d875163e5325 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import AppIntents
import Foundation
import SwiftUI
import WidgetKit
struct AccountQuery: EntityQuery {
func entities(for identifiers: [String]) async throws -> [AccountDetail] {
AccountDetail.allAccounts().filter { identifiers.contains($0.id) }
}
func suggestedEntities() async throws -> [AccountDetail] {
AccountDetail.allAccounts()
}
func defaultResult() async -> AccountDetail? {
let defaultAccountName = String(
localized: "IDS_IOS_WIDGET_KIT_EXTENSION_DEFAULT_ACCOUNT_LABEL")
return AccountDetail(id: "Default", email: defaultAccountName)
}
}
struct AccountDetail: AppEntity {
// Id contains the gaia id of the account or "Default" for the "No account" case.
let id: String
let email: String
static let typeDisplayRepresentation: TypeDisplayRepresentation = "Account"
static let defaultQuery = AccountQuery()
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(email)")
}
static func allAccounts() -> [AccountDetail] {
guard let sharedDefaults: UserDefaults = AppGroupHelper.groupUserDefaults()
else { return [] }
guard
let accounts = sharedDefaults.object(forKey: "ios.registered_accounts_on_device")
as? [String: [String: Any]]
else { return [] }
var accountsDetail: [AccountDetail] = []
let defaultAccountName = String(
localized: "IDS_IOS_WIDGET_KIT_EXTENSION_DEFAULT_ACCOUNT_LABEL")
accountsDetail.append(AccountDetail(id: "Default", email: defaultAccountName))
// Only add the Default account to the list of accounts if multi-profile flag is not enabled.
if !MultiprofileEnabled() { return accountsDetail }
let noAccountName = String(
localized: "IDS_IOS_WIDGET_KIT_EXTENSION_NO_ACCOUNT_LABEL")
accountsDetail.append(AccountDetail(id: "No account", email: noAccountName))
for (key, value) in accounts {
if let email = value["email"] as? String {
accountsDetail.append(AccountDetail(id: key, email: email))
}
}
return accountsDetail
}
static func MultiprofileEnabled() -> Bool {
guard let appGroup = AppGroupHelper.groupUserDefaults() else { return false }
guard let extensionsPrefs = appGroup.object(forKey: "Extension.FieldTrial") as? NSDictionary
else { return false }
guard
let shortcutsWidgetPrefs = extensionsPrefs.object(forKey: "MultiprofileKey")
as? NSDictionary
else { return false }
guard
let shortcutsWidgetEnabled = shortcutsWidgetPrefs.object(forKey: "FieldTrialValue")
as? NSNumber
else { return false }
return shortcutsWidgetEnabled == 1
}
}
@available(iOS 17, *)
struct SelectAccountIntent: WidgetConfigurationIntent {
static let title: LocalizedStringResource = "Select Account"
static let description = IntentDescription(
"Selects the account to display shortcuts for.")
@Parameter(title: "IDS_IOS_WIDGET_KIT_EXTENSION_SELECT_ACCOUNT_LABEL")
var account: AccountDetail?
// Returns the avatar linked to the account.
func avatar() -> Image? {
guard let gaia = account?.id
else { return nil }
let avatarFilePath =
AppGroupHelper.widgetsAvatarFolder().appendingPathComponent("\(gaia).png")
guard let uiImage = UIImage(contentsOfFile: avatarFilePath.path) else {
return nil
}
return Image(uiImage: uiImage)
}
// Returns the gaiaID linked to the account.
func gaia() -> String? {
guard let gaia = account?.id
else { return nil }
return gaia
}
// Returns a boolean used to check if the account was deleted from device.
func deleted() -> Bool {
return account?.id == nil
}
}