UX Update for user profile screen and room member details (#2822)

This commit is contained in:
Mauro
2024-05-09 17:41:09 +02:00
committed by GitHub
parent 1166400312
commit 783eab2a8a
56 changed files with 243 additions and 147 deletions
@@ -63,6 +63,7 @@
"action_leave_room" = "Leave room";
"action_manage_account" = "Manage account";
"action_manage_devices" = "Manage devices";
"action_message" = "Message";
"action_next" = "Next";
"action_no" = "No";
"action_not_now" = "Not now";
@@ -176,6 +176,14 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
}
}
private func presentCallScreen(roomID: String) async {
guard let roomProxy = await userSession.clientProxy.roomForIdentifier(roomID) else {
return
}
actionsSubject.send(.presentCallScreen(roomProxy: roomProxy))
}
private func handleRoomRoute(roomID: String, focussedEventID: String? = nil, animated: Bool) async {
guard roomID == self.roomID else { fatalError("Navigation route doesn't belong to this room flow.") }
@@ -1064,6 +1072,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
stateMachine.tryEvent(.presentUserProfile(userID: userID))
case .openDirectChat(let roomID):
stateMachine.tryEvent(.startChildFlow(roomID: roomID, entryPoint: .room))
case .startCall(let roomID):
Task { await self.presentCallScreen(roomID: roomID) }
}
}
.store(in: &cancellables)
@@ -1087,6 +1097,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
switch action {
case .openDirectChat(let roomID):
stateMachine.tryEvent(.startChildFlow(roomID: roomID, entryPoint: .room))
case .startCall(let roomID):
Task { await self.presentCallScreen(roomID: roomID) }
case .dismiss:
break // Not supported when pushed.
}
@@ -1094,9 +1106,12 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
.store(in: &cancellables)
// Replace the RoomMemberDetailsScreen without any animation.
navigationStackCoordinator.pop(animated: false)
navigationStackCoordinator.push(coordinator, animated: false) { [weak self] in
self?.stateMachine.tryEvent(.dismissUserProfile)
// If this pop and push happens before the previous navigation is completed it might break screen presentation logic
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
self.navigationStackCoordinator.pop(animated: false)
self.navigationStackCoordinator.push(coordinator, animated: false) { [weak self] in
self?.stateMachine.tryEvent(.dismissUserProfile)
}
}
}
@@ -238,10 +238,10 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
stateMachine.processEvent(.showUserProfileScreen(userID: userID), userInfo: .init(animated: animated))
case .genericCallLink(let url):
navigationSplitCoordinator.setSheetCoordinator(GenericCallLinkCoordinator(parameters: .init(url: url)), animated: animated)
case .oidcCallback:
break
case .settings, .chatBackupSettings:
settingsFlowCoordinator.handleAppRoute(appRoute, animated: animated)
case .oidcCallback:
break
}
}
@@ -595,6 +595,14 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
navigationSplitCoordinator.setSheetCoordinator(callScreenCoordinator, animated: true)
}
private func presentCallScreen(roomID: String) async {
guard let roomProxy = await userSession.clientProxy.roomForIdentifier(roomID) else {
return
}
presentCallScreen(roomProxy: roomProxy)
}
// MARK: Secure backup confirmation
private func presentSecureBackupLogoutConfirmationScreen() {
@@ -706,6 +714,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
case .openDirectChat(let roomID):
navigationSplitCoordinator.setSheetCoordinator(nil)
stateMachine.processEvent(.selectRoom(roomID: roomID, entryPoint: .room))
case .startCall(let roomID):
Task { await self.presentCallScreen(roomID: roomID) }
case .dismiss:
navigationSplitCoordinator.setSheetCoordinator(nil)
}
+2
View File
@@ -160,6 +160,8 @@ internal enum L10n {
internal static var actionManageAccount: String { return L10n.tr("Localizable", "action_manage_account") }
/// Manage devices
internal static var actionManageDevices: String { return L10n.tr("Localizable", "action_manage_devices") }
/// Message
internal static var actionMessage: String { return L10n.tr("Localizable", "action_message") }
/// Next
internal static var actionNext: String { return L10n.tr("Localizable", "action_next") }
/// No
@@ -22,19 +22,22 @@ struct FormActionButtonStyle: ButtonStyle {
let title: String
func makeBody(configuration: Configuration) -> some View {
VStack(spacing: 8) {
VStack(spacing: 4) {
configuration.label
.buttonStyle(.plain)
.foregroundColor(.compound.textPrimary)
.scaledFrame(size: 54)
.background {
RoundedRectangle(cornerRadius: 16)
.fill(configuration.isPressed ? Color.compound.bgSubtlePrimary : .compound.bgCanvasDefaultLevel1)
}
.foregroundColor(.compound.iconSecondary)
.scaledFrame(size: 24)
Text(title)
.foregroundColor(.compound.textSecondary)
.font(.compound.bodyMD)
.foregroundColor(.compound.textPrimary)
.font(.compound.bodyLG)
}
.padding(.horizontal, 4)
.padding(.vertical, 8)
.frame(maxWidth: .infinity)
.background {
RoundedRectangle(cornerRadius: 14)
.fill(configuration.isPressed ? Color.compound.bgSubtlePrimary : .compound.bgCanvasDefaultLevel1)
}
}
}
@@ -106,6 +106,10 @@ struct AvatarHeaderView<Footer: View>: View {
}
.frame(maxWidth: .infinity, alignment: .center)
.listRowBackground(Color.clear)
.listRowInsets(EdgeInsets(top: 11,
leading: 0,
bottom: 11,
trailing: 0))
}
}
@@ -97,7 +97,7 @@ struct RoomDetailsScreen: View {
@ViewBuilder
private var headerSectionShortcuts: some View {
HStack(spacing: 32) {
HStack(spacing: 8) {
ForEach(context.viewState.shortcuts, id: \.self) { shortcut in
switch shortcut {
case .mute:
@@ -29,6 +29,7 @@ struct RoomMemberDetailsScreenCoordinatorParameters {
enum RoomMemberDetailsScreenCoordinatorAction {
case openUserProfile
case openDirectChat(roomID: String)
case startCall(roomID: String)
}
final class RoomMemberDetailsScreenCoordinator: CoordinatorProtocol {
@@ -59,6 +60,8 @@ final class RoomMemberDetailsScreenCoordinator: CoordinatorProtocol {
actionsSubject.send(.openUserProfile)
case .openDirectChat(let roomID):
actionsSubject.send(.openDirectChat(roomID: roomID))
case .startCall(let roomID):
actionsSubject.send(.startCall(roomID: roomID))
}
}
.store(in: &cancellables)
@@ -19,6 +19,7 @@ import Foundation
enum RoomMemberDetailsScreenViewModelAction {
case openUserProfile
case openDirectChat(roomID: String)
case startCall(roomID: String)
}
struct RoomMemberDetailsScreenViewState: BindableState {
@@ -26,6 +27,7 @@ struct RoomMemberDetailsScreenViewState: BindableState {
var memberDetails: RoomMemberDetails?
var isOwnMemberDetails = false
var isProcessingIgnoreRequest = false
var dmRoomID: String?
var bindings: RoomMemberDetailsScreenViewStateBindings
}
@@ -83,6 +85,7 @@ enum RoomMemberDetailsScreenViewAction {
case unignoreConfirmed
case displayAvatar
case openDirectChat
case startCall(roomID: String)
}
enum RoomMemberDetailsScreenError: Hashable {
@@ -61,6 +61,12 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro
roomMemberProxy = member
state.memberDetails = RoomMemberDetails(withProxy: member)
state.isOwnMemberDetails = member.userID == roomProxy.ownUserID
switch await clientProxy.directRoomForUserID(member.userID) {
case .success(let roomID):
state.dmRoomID = roomID
case .failure:
break
}
case .failure(let error):
MXLog.warning("Failed to find member: \(error)")
actionsSubject.send(.openUserProfile)
@@ -91,6 +97,8 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro
Task { await displayFullScreenAvatar() }
case .openDirectChat:
Task { await openDirectChat() }
case .startCall(let roomID):
actionsSubject.send(.startCall(roomID: roomID))
}
}
@@ -25,7 +25,6 @@ struct RoomMemberDetailsScreen: View {
headerSection
if context.viewState.memberDetails != nil, !context.viewState.isOwnMemberDetails {
directChatSection
blockUserSection
}
}
@@ -39,6 +38,38 @@ struct RoomMemberDetailsScreen: View {
// MARK: - Private
@ViewBuilder
private var otherUserFooter: some View {
HStack(spacing: 8) {
if context.viewState.memberDetails != nil, !context.viewState.isOwnMemberDetails {
Button {
context.send(viewAction: .openDirectChat)
} label: {
CompoundIcon(\.chat)
}
.buttonStyle(FormActionButtonStyle(title: L10n.commonMessage))
.accessibilityIdentifier(A11yIdentifiers.roomMemberDetailsScreen.directChat)
}
if let roomID = context.viewState.dmRoomID {
Button {
context.send(viewAction: .startCall(roomID: roomID))
} label: {
CompoundIcon(\.videoCall)
}
.buttonStyle(FormActionButtonStyle(title: L10n.actionCall))
}
if let permalink = context.viewState.memberDetails?.permalink {
ShareLink(item: permalink) {
CompoundIcon(\.shareIos)
}
.buttonStyle(FormActionButtonStyle(title: L10n.actionShare))
}
}
.padding(.top, 32)
}
@ViewBuilder
private var headerSection: some View {
if let memberDetails = context.viewState.memberDetails {
@@ -47,15 +78,7 @@ struct RoomMemberDetailsScreen: View {
imageProvider: context.imageProvider) {
context.send(viewAction: .displayAvatar)
} footer: {
if let permalink = memberDetails.permalink {
HStack(spacing: 32) {
ShareLink(item: permalink) {
CompoundIcon(\.shareIos)
}
.buttonStyle(FormActionButtonStyle(title: L10n.actionShare))
}
.padding(.top, 32)
}
otherUserFooter
}
} else {
AvatarHeaderView(user: UserProfileProxy(userID: context.viewState.userID),
@@ -65,17 +88,6 @@ struct RoomMemberDetailsScreen: View {
}
}
private var directChatSection: some View {
Section {
ListRow(label: .default(title: L10n.commonDirectChat,
icon: \.chat),
kind: .button {
context.send(viewAction: .openDirectChat)
})
.accessibilityIdentifier(A11yIdentifiers.roomMemberDetailsScreen.directChat)
}
}
@ViewBuilder
private var blockUserSection: some View {
if let memberDetails = context.viewState.memberDetails {
@@ -134,9 +146,16 @@ struct RoomMemberDetailsScreen_Previews: PreviewProvider, TestablePreview {
let roomProxyMock = RoomProxyMock(with: .init(name: ""))
roomProxyMock.getMemberUserIDReturnValue = .success(member)
let clientProxyMock = ClientProxyMock(.init())
// to avoid mock the call state for the account owner test case
if member.userID != RoomMemberProxyMock.mockMe.userID {
clientProxyMock.directRoomForUserIDReturnValue = .success("roomID")
}
return RoomMemberDetailsScreenViewModel(userID: member.userID,
roomProxy: roomProxyMock,
clientProxy: ClientProxyMock(.init()),
clientProxy: clientProxyMock,
mediaProvider: MockMediaProvider(),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
analytics: ServiceLocator.shared.analytics)
@@ -28,6 +28,7 @@ struct UserProfileScreenCoordinatorParameters {
enum UserProfileScreenCoordinatorAction {
case openDirectChat(roomID: String)
case startCall(roomID: String)
case dismiss
}
@@ -57,6 +58,8 @@ final class UserProfileScreenCoordinator: CoordinatorProtocol {
switch action {
case .openDirectChat(let roomID):
actionsSubject.send(.openDirectChat(roomID: roomID))
case .startCall(let roomID):
actionsSubject.send(.startCall(roomID: roomID))
case .dismiss:
actionsSubject.send(.dismiss)
}
@@ -18,6 +18,7 @@ import Foundation
enum UserProfileScreenViewModelAction {
case openDirectChat(roomID: String)
case startCall(roomID: String)
case dismiss
}
@@ -28,6 +29,7 @@ struct UserProfileScreenViewState: BindableState {
var userProfile: UserProfileProxy?
var permalink: URL?
var dmRoomID: String?
var bindings: UserProfileScreenViewStateBindings
}
@@ -42,6 +44,7 @@ struct UserProfileScreenViewStateBindings {
enum UserProfileScreenViewAction {
case displayAvatar
case openDirectChat
case startCall(roomID: String)
case dismiss
}
@@ -59,6 +59,12 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
case .success(let userProfile):
state.userProfile = userProfile
state.permalink = (try? matrixToUserPermalink(userId: userID)).flatMap(URL.init(string:))
switch await clientProxy.directRoomForUserID(userProfile.userID) {
case .success(let roomID):
state.dmRoomID = roomID
case .failure:
break
}
case .failure(let error):
state.bindings.alertInfo = .init(id: .unknown)
MXLog.error("Failed to find user profile: \(error)")
@@ -81,6 +87,8 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
Task { await displayFullScreenAvatar() }
case .openDirectChat:
Task { await openDirectChat() }
case .startCall(let roomID):
actionsSubject.send(.startCall(roomID: roomID))
case .dismiss:
actionsSubject.send(.dismiss)
}
@@ -23,10 +23,6 @@ struct UserProfileScreen: View {
var body: some View {
Form {
headerSection
if context.viewState.userProfile != nil, !context.viewState.isOwnUser {
directChatSection
}
}
.compoundList()
.navigationTitle(L10n.screenRoomMemberDetailsTitle)
@@ -39,6 +35,38 @@ struct UserProfileScreen: View {
// MARK: - Private
@ViewBuilder
private var otherUserFooter: some View {
HStack(spacing: 8) {
if context.viewState.userProfile != nil, !context.viewState.isOwnUser {
Button {
context.send(viewAction: .openDirectChat)
} label: {
CompoundIcon(\.chat)
}
.buttonStyle(FormActionButtonStyle(title: L10n.commonMessage))
.accessibilityIdentifier(A11yIdentifiers.roomMemberDetailsScreen.directChat)
}
if let roomID = context.viewState.dmRoomID {
Button {
context.send(viewAction: .startCall(roomID: roomID))
} label: {
CompoundIcon(\.videoCall)
}
.buttonStyle(FormActionButtonStyle(title: L10n.actionCall))
}
if let permalink = context.viewState.permalink {
ShareLink(item: permalink) {
CompoundIcon(\.shareIos)
}
.buttonStyle(FormActionButtonStyle(title: L10n.actionShare))
}
}
.padding(.top, 32)
}
@ViewBuilder
private var headerSection: some View {
if let userProfile = context.viewState.userProfile {
@@ -47,15 +75,7 @@ struct UserProfileScreen: View {
imageProvider: context.imageProvider) {
context.send(viewAction: .displayAvatar)
} footer: {
if let permalink = context.viewState.permalink {
HStack(spacing: 32) {
ShareLink(item: permalink) {
CompoundIcon(\.shareIos)
}
.buttonStyle(FormActionButtonStyle(title: L10n.actionShare))
}
.padding(.top, 32)
}
otherUserFooter
}
} else {
AvatarHeaderView(user: UserProfileProxy(userID: context.viewState.userID),
@@ -65,17 +85,6 @@ struct UserProfileScreen: View {
}
}
private var directChatSection: some View {
Section {
ListRow(label: .default(title: L10n.commonDirectChat,
icon: \.chat),
kind: .button {
context.send(viewAction: .openDirectChat)
})
.accessibilityIdentifier(A11yIdentifiers.roomMemberDetailsScreen.directChat)
}
}
@ToolbarContentBuilder
private var toolbar: some ToolbarContent {
if context.viewState.isPresentedModally {
@@ -104,11 +113,15 @@ struct UserProfileScreen_Previews: PreviewProvider, TestablePreview {
}
static func makeViewModel(userID: String) -> UserProfileScreenViewModel {
UserProfileScreenViewModel(userID: userID,
isPresentedModally: false,
clientProxy: ClientProxyMock(.init()),
mediaProvider: MockMediaProvider(),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
analytics: ServiceLocator.shared.analytics)
let clientProxyMock = ClientProxyMock(.init())
if userID != RoomMemberProxyMock.mockMe.userID {
clientProxyMock.directRoomForUserIDReturnValue = .success("roomID")
}
return UserProfileScreenViewModel(userID: userID,
isPresentedModally: false,
clientProxy: clientProxyMock,
mediaProvider: MockMediaProvider(),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
analytics: ServiceLocator.shared.analytics)
}
}
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c2eddb648a0298d35c9ed697aefaf89ce609f58c0d3ba9fdb0b2c1cd892594fd
size 123637
oid sha256:a5b9f5e0db05f4beda9e4d7cd08c8a353a85c64a21988c6c9ec71956b4444eae
size 124255
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c2eddb648a0298d35c9ed697aefaf89ce609f58c0d3ba9fdb0b2c1cd892594fd
size 123637
oid sha256:a5b9f5e0db05f4beda9e4d7cd08c8a353a85c64a21988c6c9ec71956b4444eae
size 124255
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e02beede3f2a35a44b403435c8634d20cc9a120141dd7973f158c3c755914247
size 73050
oid sha256:8c04d77ffec96df07cbbe034347a267f56c832d1fccac0d8fde0c9a592525349
size 73216
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e02beede3f2a35a44b403435c8634d20cc9a120141dd7973f158c3c755914247
size 73050
oid sha256:8c04d77ffec96df07cbbe034347a267f56c832d1fccac0d8fde0c9a592525349
size 73216
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a70bb5fdd345057464613c8d8d915bb30aeaf340b709299270c100482b4bf4aa
size 80297
oid sha256:0fea52f76951ad2252887444caeb73ca9c8998275cdafca51e0aef97cdf745b9
size 81212
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a70bb5fdd345057464613c8d8d915bb30aeaf340b709299270c100482b4bf4aa
size 80297
oid sha256:0fea52f76951ad2252887444caeb73ca9c8998275cdafca51e0aef97cdf745b9
size 81212
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cf3ba4bb678c7c5c3c5abbef122cf97eef5df819470812f501b76528beb12ddb
size 35416
oid sha256:b07080055d6ff55e0e2d326f9696d5bb05240702251a881052c63fd0595e102c
size 36488
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cf3ba4bb678c7c5c3c5abbef122cf97eef5df819470812f501b76528beb12ddb
size 35416
oid sha256:b07080055d6ff55e0e2d326f9696d5bb05240702251a881052c63fd0595e102c
size 36488
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:99457e77405391a3be5b12d4513053bc22ee38146b0a026480206d622b5340cb
size 232976
oid sha256:993bde979b9cf5177f1b04069cd5dbb2058fb699f1dd531aa872d3b413cb810c
size 243685
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8cf3d6d752e771fca995ad3d7283fbee60bfd7614d22097f033b3bf1f91ab78b
size 233824
oid sha256:edbb5601a3b3dd48ff43910cad90b1cabff8ea99392d5e406c2ea645801b4b98
size 235619
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b31fa22226801415c912eba75810f02d40ac49a6fd1a4381d626ea1bb2bfee0c
size 174497
oid sha256:53f61afa3672b847e50aee527a24c1cdf45b7892fc1155f5fe35e19459a87ddf
size 180791
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:75751372beb8547f0a22636a16f494c48f850e8e2de3e663e3bf8b3c99380265
size 295815
oid sha256:9308508c97fe4beb9dfede048f625ee56cac2d51dba45eb98770eb55439406bd
size 301330
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dd8485c8079834b2346e203f6ce396ca7c8704d353fb34d9453804d7d72a6a47
size 278745
oid sha256:05e5b40e37fd79e246442ac554d1c9524aa69d79c5aa3b3f0c38ae083b8aeb52
size 282353
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:78a38dcd6b66c838c6c3ec33098a11bc064d2c33f4b296973ad7b9f65c55248a
size 227514
oid sha256:8a84cd11210a1a2ff6ee4b263b6234db0506fa1ddcbf65b313a2a23f4073460d
size 238709
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:512606e0e6220ff71d4fce5441021e85f0f30c7ec7f1f29c584700113c8da9d1
size 179884
oid sha256:962394bd9d8afb3061818822d1745e43bf79e1cce148fe40ec851bc901afe3cf
size 181482
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:64fce215cb9b466276f55f01c04c6a32f11c2108c09a96123a6e8ff573900936
size 158911
oid sha256:3b090ad72c576f703f002b6ae5cbb5b143f491a856eca9b4c02c9bd99b3f2809
size 160547
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:51267cc2b70adcbbeb6c5df6d7560c9a49c58437cb04ab31d6fd05b7d3ad7bf9
size 114025
oid sha256:d1d6105a1c59caf5c6e7edca31faa51667feabde732ef7c9951d2c35937c74cb
size 114559
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8f87d0ddaf6ae6b287f75a4963a749e6350c185b850188b52ff4ad7d50cefa77
size 210205
oid sha256:d70f72e041f7e569fd99f7e8a63e62bbb92a2aaedf03cdbd67a158d9fa885145
size 222061
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:58018bea77f7b28dfa0bbfe6bf0b16398bd159af2bd245f3d483eb1e99c68007
size 196330
oid sha256:eec17eea97add9dec4b238f458905ad40dcdc6f4d302bc3aca6f1f424a30bd3e
size 198643
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c7625aa1976b07cc0759f2431f6a44ada887f3927c816be128a45d14642c25da
size 152736
oid sha256:79a57e83b5432cd57652f444c96af0bff54ab20b8fbca663e38261237acc2f2c
size 153273
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bee936322c7945f72ab11e079e26c367fd782ed883a05ec8c33da82385522ba6
size 119262
oid sha256:b59dc444120d040baba15dc5322e00acf10c8afeba97fddbae2aea31a88ff7bf
size 120302
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8ec35e3ebcd15298f7d4f7e196c593bb7e23f4574c84bcd4c6f12567f1748c9a
size 124211
oid sha256:e69ee9a2b3e21dce64a57d5664173480b49b49e7e70952ccfb8a74837e7e4297
size 127058
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f3877939ae180b3a1aae3b972de0d22f0f8eb27e46b23250349873e4090d4a52
size 139981
oid sha256:00ae153e9298e2171ed34572aa11db1e82faca3a2654c7fd3f76c0cf8509369e
size 143045
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8ff200cd13ec2dd401b87a29c8e052d2cbd117abd97580d9c4ea013c8bd53f9a
size 122432
oid sha256:08b1f2e462d2b3fee6ef422fae0552195efb849dab814174d506f98a7a71a9fb
size 124405
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3405f914a5d00764b852d8c5fcbb34b1f0a01adc84e629e1e15892a22425476a
size 138854
oid sha256:f47d3d5d886babe9176b2e1641eedd4102525648fe2e04e33db7db587b31d8d9
size 142258
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:654f4ed07206e3b447a9eddd8fdd3656f9c619261656a59abd40cc83d8ccbe93
size 154414
oid sha256:41d004bf2eead94cd40c0ffbb344bc5b471a5aa811a4164b3c5c7513acbb28ad
size 158265
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0a1a9da6128d63577051c4e5f8038f289a663684cbfebaac2b2d0d8cb0c25a9f
size 68084
oid sha256:f6f8727b80f45320b3e11a836115a0ee7236a6cf709833b364718679c574cdc5
size 68755
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c4d8f29bf227dad82d7205b0a1de7cde3ff43f23ea75dd5b3baded488f26e1b9
size 75340
oid sha256:2c0a42eccfde2736e4ba39ecd0f130a5eea4aa08b824f21eef4d2edc4246b3a0
size 75605
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2953ae81a69f0adeb0445b15616e2bf5ff54dac822c3ed2010ae9b4804322b95
size 87984
oid sha256:e3962a70728c6f3c4fd976e3d7d83badfe618094a13fa5f824b93a0bd9836ad3
size 88597
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:380f908b5ea794fcd00d8e2ed30cdbc4e3d8b252e41492e03b0326186e0f049e
size 70245
oid sha256:17b2d906a1f52c2729b3c0f08f0abba2d1aaa188661df2c559ff6256bf2a6714
size 71214
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2c0e26cb0231c9abd1d57f4d38d899d93a7a8ab32259b1221991b8ac88b3bcc6
size 87550
oid sha256:9552cad4fffb2f1ab0855ecfaa7b1f4968cb83a4501961665cb62f3988fc7054
size 90543
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:826249c063050e52da83c81e34d0cee9023c536298df7b4db59057ead3f01c23
size 100501
oid sha256:4404ca231f490c501c7f134a57757fa7822ceb1a627a50316de829e24c72b7dc
size 103982
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e42a43a6820048238e353125067d7efc2c32c77dc5633a50a2060b468eceeefb
size 102403
oid sha256:ca1cdb9c0f157fe4869240c986f884eebd0b5205812734e07ee034f392a4ca17
size 103673
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a1cf3ad4bcc2e661971a8019be778757b640a85bed8debf7b6d31003325f2e05
size 112587
oid sha256:468214e5bb420cc0536b2b913fc3d45c8fcf795b45a4238a9bd54b9d69036b5b
size 116265
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7f9378f6ee8fe77ec5038cf87a77fad3261a79c1addb785e04db12b8a9b59003
size 105673
oid sha256:248b93a7d9532693c451c0f7ffe0597b580f143ff9cc5e5ed638416d51d1f8e6
size 107933
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b9a78887dd1a44c5d39c92c4e474c9bab5c5a858768bb990300cc40d80501561
size 121404
oid sha256:624bf89fe59faf35f169a18c06cf8985eda4d332c61dacd294cdcafb3a635b1a
size 125279
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bcb33f529761684c7564df444d2808ea72a1e6eee290c349fce6bda2e239344d
size 54899
oid sha256:9a08d07335e8af83c60875a53eda8da7c2e06591cdbe00a2447841c04eec982d
size 55310
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d555f65dd5a7296e1da5798ed7ff710b6bbd652b2dc801d1aa4decbe3a064ba3
size 62749
oid sha256:61eebfd560410b170993785e0aae41d0e1560e1d0ee6576aadc873329674b30e
size 66231
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7c7715d26bb104bb82c18ccc6ea4d363e833fe91f84219ecee57f2b66ca857c7
size 57234
oid sha256:4b86bd4439129b9132ad9a317c775b7758171d9391017fad47bc7e42173d93b8
size 58167
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d0d240b2ab4fbaaa18ea8817dcaf6ac33725cc2f73dea06c372336288bc04a0a
size 69921
oid sha256:759ff727547a456b9d1a11b980351afa0fc0e353a167f90855d03d5c4b676807
size 75796
+1
View File
@@ -0,0 +1 @@
The UX of the profile of other users has been updated.