From 403205f12b11dd3754d7948b6e3c5da1ce5d88ed Mon Sep 17 00:00:00 2001 From: Anton Yarmolenko Date: Tue, 17 Dec 2024 11:01:30 +0100 Subject: [PATCH] sync: Part 8 sync to upstream (#552) * feat: banner when register with already linked social account (#54) * fix: fix lint warnings * chore: added banner when register with already linked social account * style: changed text color --------- Co-authored-by: Anton Yarmolenko <37253+rnr@users.noreply.github.com> * chore: fix after merge * chore: update tab bar icons for selected unselected states (#81) * chore: Elm theme improvements on Profile (#82) * chore: fix after merge * fix: fix tab bar color not properly applying (#85) * fix: fix tar bar color not properly applying * chore: parity with android for discover icon * chore: added missed colors --------- Co-authored-by: Anton Yarmolenko <37253+rnr@users.noreply.github.com> Co-authored-by: Saeed Bashir --- .../Registration/SignUpViewModel.swift | 8 +++- .../Contents.json | 6 +-- .../discover.imageset/discover_inactive.svg | 3 ++ .../discovery.imageset/Frame-6.svg | 13 ------ .../learn.imageset/learn filled.svg | 10 ----- .../Contents.json | 2 +- .../learn_active.imageset/learn_active.svg | 1 + .../Contents.json | 2 +- .../learn_inactive.svg | 1 + .../profile.imageset/Frame-8.svg | 12 ------ .../profile_active.imageset}/Contents.json | 2 +- .../profile_active.svg | 3 ++ .../profile_inactive.imageset/Contents.json | 12 ++++++ .../profile_inactive.svg | 3 ++ .../Profile/bg_delete.imageset/Contents.json | 22 ---------- .../bg_delete.imageset/bg_delete 1.svg | 7 --- .../bg_delete.imageset/delete_bg_light.svg | 7 --- .../delete_char.imageset/delete_char.svg | 9 +--- .../delete_eyes.imageset/delete_eyes.svg | 7 --- .../Profile/noAvatar.imageset/Contents.json | 12 +----- .../noAvatar.imageset/Group 82 (1).svg | 20 --------- .../Profile/noAvatar.imageset/Group 82-2.svg | 20 --------- .../Profile/noAvatar.imageset/noavatar.svg | 12 ++++++ Core/Core/SwiftGen/Assets.swift | 10 ++--- Core/Core/SwiftGen/Strings.swift | 4 ++ Core/Core/en.lproj/Localizable.strings | 1 + OpenEdX/Router.swift | 3 +- OpenEdX/View/MainScreenView.swift | 43 ++++++++++++++++--- OpenEdX/View/MainScreenViewModel.swift | 41 +++++++++++++++++- .../DeleteAccount/DeleteAccountView.swift | 14 +++--- .../Presentation/Profile/ProfileView.swift | 12 +++++- .../DeleteAccountBG.colorset/Contents.json | 38 ++++++++++++++++ .../Colors/Tabbar/Contents.json | 6 +++ .../TabbarActiveColor.colorset}/Contents.json | 0 .../TabbarBGColor.colorset/Contents.json | 38 ++++++++++++++++ .../Contents.json | 38 ++++++++++++++++ Theme/Theme/SwiftGen/ThemeAssets.swift | 5 ++- Theme/Theme/Theme.swift | 7 +-- 38 files changed, 286 insertions(+), 168 deletions(-) rename Core/Core/Assets.xcassets/NavigationBar/{learn.imageset => discover.imageset}/Contents.json (53%) create mode 100644 Core/Core/Assets.xcassets/NavigationBar/discover.imageset/discover_inactive.svg delete mode 100644 Core/Core/Assets.xcassets/NavigationBar/discovery.imageset/Frame-6.svg delete mode 100644 Core/Core/Assets.xcassets/NavigationBar/learn.imageset/learn filled.svg rename Core/Core/Assets.xcassets/NavigationBar/{discovery.imageset => learn_active.imageset}/Contents.json (75%) create mode 100644 Core/Core/Assets.xcassets/NavigationBar/learn_active.imageset/learn_active.svg rename Core/Core/Assets.xcassets/NavigationBar/{profile.imageset => learn_inactive.imageset}/Contents.json (75%) create mode 100644 Core/Core/Assets.xcassets/NavigationBar/learn_inactive.imageset/learn_inactive.svg delete mode 100644 Core/Core/Assets.xcassets/NavigationBar/profile.imageset/Frame-8.svg rename Core/Core/Assets.xcassets/{Profile/delete_eyes.imageset => NavigationBar/profile_active.imageset}/Contents.json (75%) create mode 100644 Core/Core/Assets.xcassets/NavigationBar/profile_active.imageset/profile_active.svg create mode 100644 Core/Core/Assets.xcassets/NavigationBar/profile_inactive.imageset/Contents.json create mode 100644 Core/Core/Assets.xcassets/NavigationBar/profile_inactive.imageset/profile_inactive.svg delete mode 100644 Core/Core/Assets.xcassets/Profile/bg_delete.imageset/Contents.json delete mode 100644 Core/Core/Assets.xcassets/Profile/bg_delete.imageset/bg_delete 1.svg delete mode 100644 Core/Core/Assets.xcassets/Profile/bg_delete.imageset/delete_bg_light.svg delete mode 100644 Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/delete_eyes.svg delete mode 100644 Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Group 82 (1).svg delete mode 100644 Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Group 82-2.svg create mode 100644 Core/Core/Assets.xcassets/Profile/noAvatar.imageset/noavatar.svg create mode 100644 Theme/Theme/Assets.xcassets/Colors/DeleteAccountBG.colorset/Contents.json create mode 100644 Theme/Theme/Assets.xcassets/Colors/Tabbar/Contents.json rename Theme/Theme/Assets.xcassets/Colors/{TabbarColor.colorset => Tabbar/TabbarActiveColor.colorset}/Contents.json (100%) create mode 100644 Theme/Theme/Assets.xcassets/Colors/Tabbar/TabbarBGColor.colorset/Contents.json create mode 100644 Theme/Theme/Assets.xcassets/Colors/Tabbar/TabbarInactiveColor.colorset/Contents.json diff --git a/Authorization/Authorization/Presentation/Registration/SignUpViewModel.swift b/Authorization/Authorization/Presentation/Registration/SignUpViewModel.swift index 67a2c930e..8123cb1d1 100644 --- a/Authorization/Authorization/Presentation/Registration/SignUpViewModel.swift +++ b/Authorization/Authorization/Presentation/Registration/SignUpViewModel.swift @@ -195,7 +195,13 @@ public final class SignUpViewModel: ObservableObject { analytics.userLogin(method: authMethod) isShowProgress = false router.showMainOrWhatsNewScreen(sourceScreen: sourceScreen) - NotificationCenter.default.post(name: .userAuthorized, object: nil) + NotificationCenter.default.post( + name: .userAuthorized, + object: [ + "authMethod": authMethod, + "showSocialRegisterBanner": true + ] + ) } catch { update(fullName: response.name, email: response.email) self.externalToken = response.token diff --git a/Core/Core/Assets.xcassets/NavigationBar/learn.imageset/Contents.json b/Core/Core/Assets.xcassets/NavigationBar/discover.imageset/Contents.json similarity index 53% rename from Core/Core/Assets.xcassets/NavigationBar/learn.imageset/Contents.json rename to Core/Core/Assets.xcassets/NavigationBar/discover.imageset/Contents.json index 718131171..ebbbb5a65 100644 --- a/Core/Core/Assets.xcassets/NavigationBar/learn.imageset/Contents.json +++ b/Core/Core/Assets.xcassets/NavigationBar/discover.imageset/Contents.json @@ -1,15 +1,13 @@ { "images" : [ + { - "filename" : "learn filled.svg", + "filename" : "discover_inactive.svg", "idiom" : "universal" } ], "info" : { "author" : "xcode", "version" : 1 - }, - "properties" : { - "template-rendering-intent" : "template" } } diff --git a/Core/Core/Assets.xcassets/NavigationBar/discover.imageset/discover_inactive.svg b/Core/Core/Assets.xcassets/NavigationBar/discover.imageset/discover_inactive.svg new file mode 100644 index 000000000..9fbbb06c4 --- /dev/null +++ b/Core/Core/Assets.xcassets/NavigationBar/discover.imageset/discover_inactive.svg @@ -0,0 +1,3 @@ + + + diff --git a/Core/Core/Assets.xcassets/NavigationBar/discovery.imageset/Frame-6.svg b/Core/Core/Assets.xcassets/NavigationBar/discovery.imageset/Frame-6.svg deleted file mode 100644 index ab2e20696..000000000 --- a/Core/Core/Assets.xcassets/NavigationBar/discovery.imageset/Frame-6.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/Core/Core/Assets.xcassets/NavigationBar/learn.imageset/learn filled.svg b/Core/Core/Assets.xcassets/NavigationBar/learn.imageset/learn filled.svg deleted file mode 100644 index c961205bc..000000000 --- a/Core/Core/Assets.xcassets/NavigationBar/learn.imageset/learn filled.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/Core/Core/Assets.xcassets/NavigationBar/discovery.imageset/Contents.json b/Core/Core/Assets.xcassets/NavigationBar/learn_active.imageset/Contents.json similarity index 75% rename from Core/Core/Assets.xcassets/NavigationBar/discovery.imageset/Contents.json rename to Core/Core/Assets.xcassets/NavigationBar/learn_active.imageset/Contents.json index 29d880f86..7bd563b5f 100644 --- a/Core/Core/Assets.xcassets/NavigationBar/discovery.imageset/Contents.json +++ b/Core/Core/Assets.xcassets/NavigationBar/learn_active.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Frame-6.svg", + "filename" : "learn_active.svg", "idiom" : "universal" } ], diff --git a/Core/Core/Assets.xcassets/NavigationBar/learn_active.imageset/learn_active.svg b/Core/Core/Assets.xcassets/NavigationBar/learn_active.imageset/learn_active.svg new file mode 100644 index 000000000..126bdba1b --- /dev/null +++ b/Core/Core/Assets.xcassets/NavigationBar/learn_active.imageset/learn_active.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Core/Core/Assets.xcassets/NavigationBar/profile.imageset/Contents.json b/Core/Core/Assets.xcassets/NavigationBar/learn_inactive.imageset/Contents.json similarity index 75% rename from Core/Core/Assets.xcassets/NavigationBar/profile.imageset/Contents.json rename to Core/Core/Assets.xcassets/NavigationBar/learn_inactive.imageset/Contents.json index 535296614..fd526768b 100644 --- a/Core/Core/Assets.xcassets/NavigationBar/profile.imageset/Contents.json +++ b/Core/Core/Assets.xcassets/NavigationBar/learn_inactive.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Frame-8.svg", + "filename" : "learn_inactive.svg", "idiom" : "universal" } ], diff --git a/Core/Core/Assets.xcassets/NavigationBar/learn_inactive.imageset/learn_inactive.svg b/Core/Core/Assets.xcassets/NavigationBar/learn_inactive.imageset/learn_inactive.svg new file mode 100644 index 000000000..7618fe82f --- /dev/null +++ b/Core/Core/Assets.xcassets/NavigationBar/learn_inactive.imageset/learn_inactive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Core/Core/Assets.xcassets/NavigationBar/profile.imageset/Frame-8.svg b/Core/Core/Assets.xcassets/NavigationBar/profile.imageset/Frame-8.svg deleted file mode 100644 index f1a26b728..000000000 --- a/Core/Core/Assets.xcassets/NavigationBar/profile.imageset/Frame-8.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/Contents.json b/Core/Core/Assets.xcassets/NavigationBar/profile_active.imageset/Contents.json similarity index 75% rename from Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/Contents.json rename to Core/Core/Assets.xcassets/NavigationBar/profile_active.imageset/Contents.json index 19c371f58..6ba923c1e 100644 --- a/Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/Contents.json +++ b/Core/Core/Assets.xcassets/NavigationBar/profile_active.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "delete_eyes.svg", + "filename" : "profile_active.svg", "idiom" : "universal" } ], diff --git a/Core/Core/Assets.xcassets/NavigationBar/profile_active.imageset/profile_active.svg b/Core/Core/Assets.xcassets/NavigationBar/profile_active.imageset/profile_active.svg new file mode 100644 index 000000000..0cb94d64e --- /dev/null +++ b/Core/Core/Assets.xcassets/NavigationBar/profile_active.imageset/profile_active.svg @@ -0,0 +1,3 @@ + + + diff --git a/Core/Core/Assets.xcassets/NavigationBar/profile_inactive.imageset/Contents.json b/Core/Core/Assets.xcassets/NavigationBar/profile_inactive.imageset/Contents.json new file mode 100644 index 000000000..f4857629a --- /dev/null +++ b/Core/Core/Assets.xcassets/NavigationBar/profile_inactive.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "profile_inactive.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Core/Core/Assets.xcassets/NavigationBar/profile_inactive.imageset/profile_inactive.svg b/Core/Core/Assets.xcassets/NavigationBar/profile_inactive.imageset/profile_inactive.svg new file mode 100644 index 000000000..48abd9656 --- /dev/null +++ b/Core/Core/Assets.xcassets/NavigationBar/profile_inactive.imageset/profile_inactive.svg @@ -0,0 +1,3 @@ + + + diff --git a/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/Contents.json b/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/Contents.json deleted file mode 100644 index 118426dbb..000000000 --- a/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "filename" : "delete_bg_light.svg", - "idiom" : "universal" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "filename" : "bg_delete 1.svg", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/bg_delete 1.svg b/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/bg_delete 1.svg deleted file mode 100644 index 92b146822..000000000 --- a/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/bg_delete 1.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/delete_bg_light.svg b/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/delete_bg_light.svg deleted file mode 100644 index 96007a9b5..000000000 --- a/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/delete_bg_light.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/Core/Core/Assets.xcassets/Profile/delete_char.imageset/delete_char.svg b/Core/Core/Assets.xcassets/Profile/delete_char.imageset/delete_char.svg index d1422ad6a..629486222 100644 --- a/Core/Core/Assets.xcassets/Profile/delete_char.imageset/delete_char.svg +++ b/Core/Core/Assets.xcassets/Profile/delete_char.imageset/delete_char.svg @@ -1,8 +1,3 @@ - - - - - - - + + diff --git a/Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/delete_eyes.svg b/Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/delete_eyes.svg deleted file mode 100644 index af854563b..000000000 --- a/Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/delete_eyes.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Contents.json b/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Contents.json index a92e0ba79..39a9d81a0 100644 --- a/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Contents.json +++ b/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Contents.json @@ -1,17 +1,7 @@ { "images" : [ { - "filename" : "Group 82 (1).svg", - "idiom" : "universal" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "filename" : "Group 82-2.svg", + "filename" : "noavatar.svg", "idiom" : "universal" } ], diff --git a/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Group 82 (1).svg b/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Group 82 (1).svg deleted file mode 100644 index 378c7d3c7..000000000 --- a/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Group 82 (1).svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Group 82-2.svg b/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Group 82-2.svg deleted file mode 100644 index 787fcfd88..000000000 --- a/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/Group 82-2.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/noavatar.svg b/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/noavatar.svg new file mode 100644 index 000000000..af8187de2 --- /dev/null +++ b/Core/Core/Assets.xcassets/Profile/noAvatar.imageset/noavatar.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Core/Core/SwiftGen/Assets.swift b/Core/Core/SwiftGen/Assets.swift index 14c34ddcf..0b846c4a9 100644 --- a/Core/Core/SwiftGen/Assets.swift +++ b/Core/Core/SwiftGen/Assets.swift @@ -76,16 +76,16 @@ public enum CoreAssets { public static let noAnnouncements = ImageAsset(name: "noAnnouncements") public static let noHandouts = ImageAsset(name: "noHandouts") public static let dashboard = ImageAsset(name: "dashboard") - public static let discovery = ImageAsset(name: "discovery") - public static let learn = ImageAsset(name: "learn") - public static let profile = ImageAsset(name: "profile") + public static let discover = ImageAsset(name: "discover") + public static let learnActive = ImageAsset(name: "learn_active") + public static let learnInactive = ImageAsset(name: "learn_inactive") + public static let profileActive = ImageAsset(name: "profile_active") + public static let profileInactive = ImageAsset(name: "profile_inactive") public static let programs = ImageAsset(name: "programs") public static let addPhoto = ImageAsset(name: "addPhoto") - public static let bgDelete = ImageAsset(name: "bg_delete") public static let checkmark = ImageAsset(name: "checkmark") public static let deleteAccount = ImageAsset(name: "deleteAccount") public static let deleteChar = ImageAsset(name: "delete_char") - public static let deleteEyes = ImageAsset(name: "delete_eyes") public static let done = ImageAsset(name: "done") public static let gallery = ImageAsset(name: "gallery") public static let leaveProfile = ImageAsset(name: "leaveProfile") diff --git a/Core/Core/SwiftGen/Strings.swift b/Core/Core/SwiftGen/Strings.swift index 672300224..efae8f823 100644 --- a/Core/Core/SwiftGen/Strings.swift +++ b/Core/Core/SwiftGen/Strings.swift @@ -224,6 +224,10 @@ public enum CoreLocalization { public static let profile = CoreLocalization.tr("Localizable", "MAINSCREEN.PROFILE", fallback: "Profile") /// Programs public static let programs = CoreLocalization.tr("Localizable", "MAINSCREEN.PROGRAMS", fallback: "Programs") + /// You already set up an %@ account with your %@ account. You have been logged in with that account. + public static func socialRegisterBanner(_ p1: Any, _ p2: Any) -> String { + return CoreLocalization.tr("Localizable", "MAINSCREEN.SOCIAL_REGISTER_BANNER", String(describing: p1), String(describing: p2), fallback: "You already set up an %@ account with your %@ account. You have been logged in with that account.") + } } public enum NoInternet { /// Dismiss diff --git a/Core/Core/en.lproj/Localizable.strings b/Core/Core/en.lproj/Localizable.strings index 97d00ae26..612975633 100644 --- a/Core/Core/en.lproj/Localizable.strings +++ b/Core/Core/en.lproj/Localizable.strings @@ -12,6 +12,7 @@ "MAINSCREEN.PROGRAMS" = "Programs"; "MAINSCREEN.PROFILE" = "Profile"; "MAINSCREEN.LEARN" = "Learn"; +"MAINSCREEN.SOCIAL_REGISTER_BANNER" = "You already set up an %@ account with your %@ account. You have been logged in with that account."; "VIEW.SNACKBAR.TRY_AGAIN_BTN" = "Try Again"; diff --git a/OpenEdX/Router.swift b/OpenEdX/Router.swift index e0b742369..4cb43429c 100644 --- a/OpenEdX/Router.swift +++ b/OpenEdX/Router.swift @@ -541,7 +541,8 @@ public class Router: AuthorizationRouter, verticalIndex: verticalPosition ?? 0, chapters: courseStructure.childs, chapterIndex: chapterPosition ?? 0, - sequentialIndex: sequentialPosition ?? 0) + sequentialIndex: sequentialPosition ?? 0 + ) } } else if !blockLink.isEmpty, let blockURL = URL(string: blockLink) { DispatchQueue.main.async { [weak self] in diff --git a/OpenEdX/View/MainScreenView.swift b/OpenEdX/View/MainScreenView.swift index f8d4a6200..2b4476286 100644 --- a/OpenEdX/View/MainScreenView.swift +++ b/OpenEdX/View/MainScreenView.swift @@ -14,6 +14,7 @@ import Profile import WhatsNew import SwiftUIIntrospect import Theme +import OEXFoundation struct MainScreenView: View { @@ -25,9 +26,9 @@ struct MainScreenView: View { init(viewModel: MainScreenViewModel) { self.viewModel = viewModel UITabBar.appearance().isTranslucent = false - UITabBar.appearance().barTintColor = UIColor(Theme.Colors.tabbarColor) - UITabBar.appearance().backgroundColor = UIColor(Theme.Colors.tabbarColor) - UITabBar.appearance().unselectedItemTintColor = UIColor(Theme.Colors.textSecondaryLight) + UITabBar.appearance().barTintColor = Theme.UIColors.tabbarActiveColor + UITabBar.appearance().backgroundColor = Theme.UIColors.tabbarBGColor + UITabBar.appearance().unselectedItemTintColor = Theme.UIColors.tabbarInactiveColor UITabBarItem.appearance().setTitleTextAttributes( [NSAttributedString.Key.font: Theme.UIFonts.labelSmall()], @@ -48,6 +49,7 @@ struct MainScreenView: View { if updateAvailable { UpdateNotificationView(config: viewModel.config) } + registerBanner } .tabItem { CoreAssets.dashboard.swiftUIImage.renderingMode(.template) @@ -55,6 +57,7 @@ struct MainScreenView: View { } .tag(MainTab.dashboard) .accessibilityIdentifier("dashboard_tabitem") + .animation(.easeInOut, value: viewModel.showRegisterBanner) if viewModel.config.program.enabled { ZStack { if viewModel.config.program.type == .webview { @@ -90,13 +93,19 @@ struct MainScreenView: View { if updateAvailable { UpdateNotificationView(config: viewModel.config) } + registerBanner } .tabItem { - CoreAssets.learn.swiftUIImage.renderingMode(.template) + if viewModel.selection == .dashboard { + CoreAssets.learnActive.swiftUIImage.renderingMode(.template) + } else { + CoreAssets.learnInactive.swiftUIImage.renderingMode(.template) + } Text(CoreLocalization.Mainscreen.learn) } .tag(MainTab.dashboard) .accessibilityIdentifier("dashboard_tabitem") + .animation(.easeInOut, value: viewModel.showRegisterBanner) } if viewModel.config.discovery.enabled { @@ -121,7 +130,7 @@ struct MainScreenView: View { } } .tabItem { - CoreAssets.discovery.swiftUIImage.renderingMode(.template) + CoreAssets.discover.swiftUIImage.renderingMode(.template) Text(CoreLocalization.Mainscreen.discovery) } .tag(MainTab.discovery) @@ -134,7 +143,11 @@ struct MainScreenView: View { ) } .tabItem { - CoreAssets.profile.swiftUIImage.renderingMode(.template) + if viewModel.selection == .profile { + CoreAssets.profileActive.swiftUIImage.renderingMode(.template) + } else { + CoreAssets.profileInactive.swiftUIImage.renderingMode(.template) + } Text(CoreLocalization.Mainscreen.profile) } .tag(MainTab.profile) @@ -193,10 +206,28 @@ struct MainScreenView: View { } viewModel.trackMainDashboardLearnTabClicked() viewModel.trackMainDashboardMyCoursesClicked() + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + viewModel.checkIfNeedToShowRegisterBanner() + } } .accentColor(Theme.Colors.accentXColor) } + @ViewBuilder + private var registerBanner: some View { + if viewModel.showRegisterBanner { + VStack { + SnackBarView(message: viewModel.registerBannerText) + Spacer() + }.transition(.move(edge: .top)) + .onAppear { + doAfter(Theme.Timeout.snackbarMessageLongTimeout) { + viewModel.registerBannerWasShowed() + } + } + } + } + private func titleBar() -> String { switch viewModel.selection { case .discovery: diff --git a/OpenEdX/View/MainScreenViewModel.swift b/OpenEdX/View/MainScreenViewModel.swift index c6404138e..599b0581a 100644 --- a/OpenEdX/View/MainScreenViewModel.swift +++ b/OpenEdX/View/MainScreenViewModel.swift @@ -12,6 +12,7 @@ import Profile import Course import Swinject import Combine +import Authorization public enum MainTab { case discovery @@ -35,7 +36,12 @@ final class MainScreenViewModel: ObservableObject { private var cancellables = Set() @Published var selection: MainTab = .dashboard - + @Published var showRegisterBanner: Bool = false + + private var shouldShowRegisterBanner: Bool = false + private var authMethod: AuthMethod? + private var cancellations: [AnyCancellable] = [] + init(analytics: MainScreenAnalytics, config: ConfigProtocol, router: BaseRouter, @@ -64,6 +70,22 @@ final class MainScreenViewModel: ObservableObject { } } .store(in: &cancellables) + addObservers() + } + + private func addObservers() { + NotificationCenter.default + .publisher(for: .userAuthorized) + .sink { [weak self] object in + guard let self, + let dict = object.object as? [String: Any], + let authMethod = dict["authMethod"] as? AuthMethod, + let shouldShowBanner = dict["showSocialRegisterBanner"] as? Bool + else { return } + self.shouldShowRegisterBanner = shouldShowBanner + self.authMethod = authMethod + } + .store(in: &cancellations) } public func select(tab: MainTab) { @@ -121,6 +143,23 @@ final class MainScreenViewModel: ObservableObject { analytics.mainCoursesClicked() } + public func checkIfNeedToShowRegisterBanner() { + if shouldShowRegisterBanner && !registerBannerText.isEmpty { + showRegisterBanner = true + } + } + public func registerBannerWasShowed() { + shouldShowRegisterBanner = false + showRegisterBanner = false + } + public var registerBannerText: String { + guard !config.platformName.isEmpty, + case .socailAuth(let socialMethod) = authMethod, + !socialMethod.rawValue.isEmpty + else { return "" } + return CoreLocalization.Mainscreen.socialRegisterBanner(config.platformName, socialMethod.rawValue.capitalized) + } + @MainActor func prefetchDataForOffline() async { if await profileInteractor.getMyProfileOffline() == nil { diff --git a/Profile/Profile/Presentation/DeleteAccount/DeleteAccountView.swift b/Profile/Profile/Presentation/DeleteAccount/DeleteAccountView.swift index 2a970f2b6..585c06279 100644 --- a/Profile/Profile/Presentation/DeleteAccount/DeleteAccountView.swift +++ b/Profile/Profile/Presentation/DeleteAccount/DeleteAccountView.swift @@ -27,12 +27,14 @@ public struct DeleteAccountView: View { VStack { Group { ZStack { - CoreAssets.bgDelete.swiftUIImage - CoreAssets.deleteChar.swiftUIImage - .foregroundColor(Theme.Colors.accentXColor) - .offset(y: -31) - CoreAssets.deleteEyes.swiftUIImage - .offset(x: -7, y: -27) + Circle() + .foregroundColor(Theme.Colors.deleteAccountBG) + .frame(width: 104, height: 104) + CoreAssets.deleteChar.swiftUIImage.renderingMode(.template) + .resizable() + .foregroundColor(Theme.Colors.white) + .frame(width: 60, height: 60) + .offset(y: -5) .accessibilityIdentifier("delete_account_image") }.padding(.top, 50) diff --git a/Profile/Profile/Presentation/Profile/ProfileView.swift b/Profile/Profile/Presentation/Profile/ProfileView.swift index 54f0026c7..dfd4b9051 100644 --- a/Profile/Profile/Presentation/Profile/ProfileView.swift +++ b/Profile/Profile/Presentation/Profile/ProfileView.swift @@ -202,14 +202,16 @@ struct ProfileView_Previews: PreviewProvider { struct UserAvatar: View { private var url: URL? + private var borderColor: Color @Binding private var image: UIImage? - init(url: String, image: Binding) { + init(url: String, image: Binding, borderColor: Color = Theme.Colors.avatarStroke) { if let rightUrl = URL(string: url) { self.url = rightUrl } else { self.url = nil } self._image = image + self.borderColor = borderColor } var body: some View { ZStack { @@ -219,6 +221,10 @@ struct UserAvatar: View { .scaledToFill() .frame(width: 80, height: 80) .cornerRadius(40) + .overlay { + Circle() + .stroke(borderColor, lineWidth: 1) + } } else { KFImage(url) .onFailureImage(CoreAssets.noCourseImage.image) @@ -226,6 +232,10 @@ struct UserAvatar: View { .scaledToFill() .frame(width: 80, height: 80) .cornerRadius(40) + .overlay { + Circle() + .stroke(borderColor, lineWidth: 1) + } } } } diff --git a/Theme/Theme/Assets.xcassets/Colors/DeleteAccountBG.colorset/Contents.json b/Theme/Theme/Assets.xcassets/Colors/DeleteAccountBG.colorset/Contents.json new file mode 100644 index 000000000..bf1a96417 --- /dev/null +++ b/Theme/Theme/Assets.xcassets/Colors/DeleteAccountBG.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "0.408", + "red" : "0.235" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF8", + "green" : "0x78", + "red" : "0x53" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Theme/Theme/Assets.xcassets/Colors/Tabbar/Contents.json b/Theme/Theme/Assets.xcassets/Colors/Tabbar/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/Theme/Theme/Assets.xcassets/Colors/Tabbar/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Theme/Theme/Assets.xcassets/Colors/TabbarColor.colorset/Contents.json b/Theme/Theme/Assets.xcassets/Colors/Tabbar/TabbarActiveColor.colorset/Contents.json similarity index 100% rename from Theme/Theme/Assets.xcassets/Colors/TabbarColor.colorset/Contents.json rename to Theme/Theme/Assets.xcassets/Colors/Tabbar/TabbarActiveColor.colorset/Contents.json diff --git a/Theme/Theme/Assets.xcassets/Colors/Tabbar/TabbarBGColor.colorset/Contents.json b/Theme/Theme/Assets.xcassets/Colors/Tabbar/TabbarBGColor.colorset/Contents.json new file mode 100644 index 000000000..7e4772ec9 --- /dev/null +++ b/Theme/Theme/Assets.xcassets/Colors/Tabbar/TabbarBGColor.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "blue" : "0xFA", + "green" : "0xF9", + "red" : "0xF8" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "display-p3", + "components" : { + "alpha" : "1.000", + "blue" : "0.275", + "green" : "0.200", + "red" : "0.153" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Theme/Theme/Assets.xcassets/Colors/Tabbar/TabbarInactiveColor.colorset/Contents.json b/Theme/Theme/Assets.xcassets/Colors/Tabbar/TabbarInactiveColor.colorset/Contents.json new file mode 100644 index 000000000..93691d3e8 --- /dev/null +++ b/Theme/Theme/Assets.xcassets/Colors/Tabbar/TabbarInactiveColor.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.733", + "green" : "0.647", + "red" : "0.592" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.624", + "green" : "0.533", + "red" : "0.475" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Theme/Theme/SwiftGen/ThemeAssets.swift b/Theme/Theme/SwiftGen/ThemeAssets.swift index 9b6caa87e..bee684564 100644 --- a/Theme/Theme/SwiftGen/ThemeAssets.swift +++ b/Theme/Theme/SwiftGen/ThemeAssets.swift @@ -46,6 +46,7 @@ public enum ThemeAssets { public static let pastDueTimelineColor = ColorAsset(name: "pastDueTimelineColor") public static let primaryHeaderColor = ColorAsset(name: "primaryHeaderColor") public static let secondaryHeaderColor = ColorAsset(name: "secondaryHeaderColor") + public static let deleteAccountBG = ColorAsset(name: "DeleteAccountBG") public static let infoColor = ColorAsset(name: "InfoColor") public static let irreversibleAlert = ColorAsset(name: "IrreversibleAlert") public static let loginBackground = ColorAsset(name: "LoginBackground") @@ -70,7 +71,9 @@ public enum ThemeAssets { public static let disabledButton = ColorAsset(name: "disabledButton") public static let disabledButtonText = ColorAsset(name: "disabledButtonText") public static let success = ColorAsset(name: "Success") - public static let tabbarColor = ColorAsset(name: "TabbarColor") + public static let tabbarActiveColor = ColorAsset(name: "TabbarActiveColor") + public static let tabbarBGColor = ColorAsset(name: "TabbarBGColor") + public static let tabbarInactiveColor = ColorAsset(name: "TabbarInactiveColor") public static let textPrimary = ColorAsset(name: "TextPrimary") public static let textSecondary = ColorAsset(name: "TextSecondary") public static let textSecondaryLight = ColorAsset(name: "TextSecondaryLight") diff --git a/Theme/Theme/Theme.swift b/Theme/Theme/Theme.swift index 221bb9ee2..884e918b8 100644 --- a/Theme/Theme/Theme.swift +++ b/Theme/Theme/Theme.swift @@ -61,7 +61,6 @@ public struct Theme: Sendable { nonisolated(unsafe) public private(set) static var secondaryButtonTextColor = ThemeAssets.secondaryButtonTextColor.swiftUIColor nonisolated(unsafe) public private(set) static var secondaryButtonBGColor = ThemeAssets.secondaryButtonBGColor.swiftUIColor nonisolated(unsafe) public private(set) static var success = ThemeAssets.success.swiftUIColor - nonisolated(unsafe) public private(set) static var tabbarColor = ThemeAssets.tabbarColor.swiftUIColor nonisolated(unsafe) public private(set) static var primaryButtonTextColor = ThemeAssets.primaryButtonTextColor.swiftUIColor nonisolated(unsafe) public private(set) static var toggleSwitchColor = ThemeAssets.toggleSwitchColor.swiftUIColor nonisolated(unsafe) public private(set) static var textInputTextColor = ThemeAssets.textInputTextColor.swiftUIColor @@ -76,6 +75,7 @@ public struct Theme: Sendable { nonisolated(unsafe) public private(set) static var courseCardShadow = ThemeAssets.courseCardShadow.swiftUIColor nonisolated(unsafe) public private(set) static var shade = ThemeAssets.shade.swiftUIColor nonisolated(unsafe) public private(set) static var courseCardBackground = ThemeAssets.courseCardBackground.swiftUIColor + nonisolated(unsafe) public private(set) static var deleteAccountBG = ThemeAssets.deleteAccountBG.swiftUIColor public static func update( accentColor: Color = ThemeAssets.accentColor.swiftUIColor, @@ -116,7 +116,6 @@ public struct Theme: Sendable { secondaryButtonBorderColor: Color = ThemeAssets.secondaryButtonBorderColor.swiftUIColor, secondaryButtonTextColor: Color = ThemeAssets.secondaryButtonTextColor.swiftUIColor, success: Color = ThemeAssets.success.swiftUIColor, - tabbarColor: Color = ThemeAssets.tabbarColor.swiftUIColor, primaryButtonTextColor: Color = ThemeAssets.primaryButtonTextColor.swiftUIColor, toggleSwitchColor: Color = ThemeAssets.toggleSwitchColor.swiftUIColor, textInputTextColor: Color = ThemeAssets.textInputTextColor.swiftUIColor, @@ -162,7 +161,6 @@ public struct Theme: Sendable { self.secondaryButtonBorderColor = secondaryButtonBorderColor self.secondaryButtonTextColor = secondaryButtonTextColor self.success = success - self.tabbarColor = tabbarColor self.primaryButtonTextColor = primaryButtonTextColor self.toggleSwitchColor = toggleSwitchColor self.textInputTextColor = textInputTextColor @@ -180,6 +178,9 @@ public struct Theme: Sendable { nonisolated(unsafe) public private(set) static var accentXColor = ThemeAssets.accentXColor.color nonisolated(unsafe) public private(set) static var navigationBarTintColor = ThemeAssets.navigationBarTintColor.color + nonisolated(unsafe) public private(set) static var tabbarActiveColor = ThemeAssets.tabbarActiveColor.color + nonisolated(unsafe) public private(set) static var tabbarBGColor = ThemeAssets.tabbarBGColor.color + nonisolated(unsafe) public private(set) static var tabbarInactiveColor = ThemeAssets.tabbarInactiveColor.color public static func update( textPrimary: UIColor = ThemeAssets.textPrimary.color,