Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix avatar images #664

Merged
merged 7 commits into from
Mar 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/kean/Nuke",
"state" : {
"revision" : "33f7e93be5d4ec027d42af77a8ec4680d1862ad2",
"version" : "11.6.4"
"revision" : "f4d9b95788679d0654c032961f73e7e9c16ca6b4",
"version" : "12.1.0"
}
},
{
Expand Down
45 changes: 45 additions & 0 deletions Mail/Components/AvatarView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
Infomaniak Mail - iOS App
Copyright (C) 2022 Infomaniak Network SA
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 <http://www.gnu.org/licenses/>.
*/

import InfomaniakCore
import MailCore
import NukeUI
import SwiftUI

struct AvatarView: View {
let avatarDisplayable: AvatarDisplayable
var size: CGFloat = 28

var body: some View {
if let avatarImageRequest = avatarDisplayable.avatarImageRequest {
LazyImage(request: avatarImageRequest) { state in
if let image = state.image {
ContactImage(image: image, size: size)
} else {
InitialsView(
initials: avatarDisplayable.initials,
color: avatarDisplayable.initialsBackgroundColor,
size: size
)
}
}
} else {
InitialsView(initials: avatarDisplayable.initials, color: avatarDisplayable.initialsBackgroundColor, size: size)
}
}
}
16 changes: 7 additions & 9 deletions Mail/Components/ContactImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,15 @@ import MailCore
import SwiftUI

struct ContactImage: View {
var image: Image
var size: CGFloat
let image: Image
let size: CGFloat

var body: some View {
ZStack {
image
.resizable()
.scaledToFit()
.frame(width: size, height: size)
.clipShape(Circle())
}
image
.resizable()
.scaledToFit()
.frame(width: size, height: size)
.clipShape(Circle())
}
}

Expand Down
2 changes: 1 addition & 1 deletion Mail/Components/RecipientAutocompletionCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct RecipientAutocompletionCell: View {

var body: some View {
HStack {
RecipientImage(recipient: recipient)
AvatarView(avatarDisplayable: recipient, size: 40)

if recipient.name.isEmpty {
Text(recipient.email)
Expand Down
59 changes: 0 additions & 59 deletions Mail/Components/RecipientImage.swift

This file was deleted.

2 changes: 1 addition & 1 deletion Mail/Components/ThreadCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ struct ThreadCell: View {
Group {
if density == .large, let recipient = dataHolder.recipientToDisplay {
ZStack {
RecipientImage(recipient: recipient)
AvatarView(avatarDisplayable: recipient, size: 40)
CheckboxView(isSelected: isSelected, density: density)
.opacity(isSelected ? 1 : 0)
}
Expand Down
2 changes: 1 addition & 1 deletion Mail/Views/Bottom sheets/ContactActionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct ContactActionsView: View {
var body: some View {
VStack(alignment: .leading, spacing: 16) {
HStack {
RecipientImage(recipient: recipient, size: 32)
AvatarView(avatarDisplayable: recipient, size: 32)
VStack(alignment: .leading) {
Text(recipient.contact?.name ?? recipient.formattedName)
.textStyle(.bodyMedium)
Expand Down
1 change: 0 additions & 1 deletion Mail/Views/SplitView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ public class SplitViewManager: ObservableObject {
@Published var showSearch = false
@Published var selectedFolder: Folder?
var splitViewController: UISplitViewController?
@Published var avatarImage = MailResourcesAsset.placeholderAvatar.swiftUIImage

init(folder: Folder?) {
selectedFolder = folder
Expand Down
11 changes: 1 addition & 10 deletions Mail/Views/Switch User/AccountCellView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,9 @@ struct AccountHeaderCell: View {
let account: Account
@Binding var isSelected: Bool

@State private var avatarImage = MailResourcesAsset.placeholderAvatar.swiftUIImage

var body: some View {
HStack(spacing: 8) {
avatarImage
.resizable()
.frame(width: 38, height: 38)
.clipShape(Circle())

AvatarView(avatarDisplayable: account.user, size: 38)
VStack(alignment: .leading, spacing: 2) {
Text(account.user.displayName)
.textStyle(.bodyMedium)
Expand All @@ -93,9 +87,6 @@ struct AccountHeaderCell: View {
.foregroundColor(.accentColor)
}
}
.task {
avatarImage = await account.user.avatarImage
}
}
}

Expand Down
10 changes: 1 addition & 9 deletions Mail/Views/Switch User/AccountView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ struct AccountView: View {

@LazyInjectService private var matomo: MatomoUtils

@State private var avatarImage = MailResourcesAsset.placeholderAvatar.swiftUIImage
private let account = AccountManager.instance.currentAccount!
@State private var isShowingLogoutAlert = false
@State private var isShowingDeleteAccount = false
Expand All @@ -63,11 +62,7 @@ struct AccountView: View {
NavigationView {
VStack(spacing: 0) {
ScrollView {
// Header
avatarImage
.resizable()
.frame(width: 104, height: 104)
.clipShape(Circle())
AvatarView(avatarDisplayable: account.user, size: 104)
.padding(.top, 24)
.padding(.bottom, 16)

Expand Down Expand Up @@ -127,9 +122,6 @@ struct AccountView: View {
Label(MailResourcesStrings.Localizable.buttonClose, systemImage: "xmark")
})
}
.task {
avatarImage = await account.user.avatarImage
}
.sheet(isPresented: $isShowingDeleteAccount) {
DeleteAccountView(account: account, delegate: delegate)
}
Expand Down
11 changes: 1 addition & 10 deletions Mail/Views/Thread List/ThreadListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -352,16 +352,7 @@ private struct ThreadListToolbar: ViewModifier {
Button {
isShowingSwitchAccount.toggle()
} label: {
splitViewManager.avatarImage
.resizable()
.scaledToFit()
.frame(width: 28, height: 28)
.clipShape(Circle())
}
.task {
if let account = AccountManager.instance.currentAccount {
splitViewManager.avatarImage = await account.user.avatarImage
}
AvatarView(avatarDisplayable: AccountManager.instance.currentAccount.user)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Mail/Views/Thread/MessageHeaderSummaryView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct MessageHeaderSummaryView: View {
matomo.track(eventWithCategory: .message, name: "selectAvatar")
recipientTapped(recipient)
} label: {
RecipientImage(recipient: recipient, size: 40)
AvatarView(avatarDisplayable: recipient, size: 40)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,24 @@
*/

import Foundation
import InfomaniakCore
import Nuke

extension ImagePipeline {
public func imageWithAuthentication(for url: URL, delegate: (any ImageTaskDelegate)? = nil) async throws -> ImageResponse {
public extension MailApiFetcher {
func avatarImageRequestForContact(_ contact: MergedContact) -> ImageRequest? {
guard let avatarPath = contact.remote?.avatar else { return nil }
let endpoint = Endpoint.resource(avatarPath)

return authenticatedImageRequest(endpoint.url)
}

func authenticatedImageRequest(_ url: URL) -> ImageRequest? {
var urlRequest = URLRequest(url: url)
urlRequest.addValue(
"Bearer \(AccountManager.instance.currentAccount.token.accessToken)",
"Bearer \(currentToken?.accessToken ?? "")",
forHTTPHeaderField: "Authorization"
)

return try await image(for: ImageRequest(urlRequest: urlRequest), delegate: delegate)
return ImageRequest(urlRequest: urlRequest)
}
}
28 changes: 0 additions & 28 deletions MailCore/Cache/AccountManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,34 +59,6 @@ public extension InfomaniakNetworkLoginable {
}
}

public extension InfomaniakUser {
var cachedAvatarImage: Image? {
if let avatarURL = URL(string: avatar),
let avatarUIImage = ImagePipeline.shared.cache[avatarURL]?.image {
return Image(uiImage: avatarUIImage)
}

return nil
}

var avatarImage: Image {
get async {
if let avatarURL = URL(string: avatar),
let avatarImage = try? await ImagePipeline.shared.image(for: avatarURL).image {
return Image(uiImage: avatarImage)
} else {
let backgroundColor = UIColor.backgroundColor(from: id, with: UIConstants.avatarColors)
let initialsImage = UIImage.getInitialsPlaceholder(
with: displayName,
size: CGSize(width: 40, height: 40),
backgroundColor: backgroundColor
)
return Image(uiImage: initialsImage)
}
}
}
}

@globalActor actor AccountActor: GlobalActor {
static let shared = AccountActor()

Expand Down
Loading