WIP: landing screen (attributed text)
This commit is contained in:
parent
2f9ca3c0f6
commit
c9d97c10d0
|
@ -159,6 +159,7 @@
|
|||
7BDCFC08242186E700641C39 /* NotificationServiceExtensionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDCFC07242186E700641C39 /* NotificationServiceExtensionContext.swift */; };
|
||||
7BDCFC0B2421EB7600641C39 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6F509951AA53F760068F56A /* Localizable.strings */; };
|
||||
7BDE2A982A8B122900AE4393 /* LandingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDE2A972A8B122900AE4393 /* LandingView.swift */; };
|
||||
7BDE2A9A2A8C59CF00AE4393 /* AttributedText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDE2A992A8C59CF00AE4393 /* AttributedText.swift */; };
|
||||
7BF8D1FB2A70AF57005F1D6E /* SwiftUI+Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF8D1FA2A70AF57005F1D6E /* SwiftUI+Theme.swift */; };
|
||||
7BFA8AE32831D0D4001876F3 /* ContextMenuVC+EmojiReactsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFA8AE22831D0D4001876F3 /* ContextMenuVC+EmojiReactsView.swift */; };
|
||||
7BFD1A8A2745C4F000FB91B9 /* Permissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFD1A892745C4F000FB91B9 /* Permissions.swift */; };
|
||||
|
@ -1274,6 +1275,7 @@
|
|||
7BDCFC0424206E7300641C39 /* SessionNotificationServiceExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SessionNotificationServiceExtension.entitlements; sourceTree = "<group>"; };
|
||||
7BDCFC07242186E700641C39 /* NotificationServiceExtensionContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationServiceExtensionContext.swift; sourceTree = "<group>"; };
|
||||
7BDE2A972A8B122900AE4393 /* LandingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LandingView.swift; sourceTree = "<group>"; };
|
||||
7BDE2A992A8C59CF00AE4393 /* AttributedText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedText.swift; sourceTree = "<group>"; };
|
||||
7BE2701D2A64C11500CEB71A /* SessionCarouselView+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionCarouselView+SwiftUI.swift"; sourceTree = "<group>"; };
|
||||
7BF8D1FA2A70AF57005F1D6E /* SwiftUI+Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SwiftUI+Theme.swift"; sourceTree = "<group>"; };
|
||||
7BFA8AE22831D0D4001876F3 /* ContextMenuVC+EmojiReactsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ContextMenuVC+EmojiReactsView.swift"; sourceTree = "<group>"; };
|
||||
|
@ -2946,6 +2948,7 @@
|
|||
C38EF2A4255B6D93007E1867 /* ProfilePictureView.swift */,
|
||||
FD71165A28E6DDBC00B47552 /* StyledNavigationController.swift */,
|
||||
FD0B77AF29B69A65009169BA /* TopBannerController.swift */,
|
||||
7BDE2A992A8C59CF00AE4393 /* AttributedText.swift */,
|
||||
);
|
||||
path = Components;
|
||||
sourceTree = "<group>";
|
||||
|
@ -5491,6 +5494,7 @@
|
|||
FD37EA0128A60473003AE748 /* UIKit+Theme.swift in Sources */,
|
||||
FD37E9CF28A1EB1B003AE748 /* Theme.swift in Sources */,
|
||||
C331FFB92558FA8D00070591 /* UIView+Constraints.swift in Sources */,
|
||||
7BDE2A9A2A8C59CF00AE4393 /* AttributedText.swift in Sources */,
|
||||
FD0B77B029B69A65009169BA /* TopBannerController.swift in Sources */,
|
||||
FD37E9F628A5F106003AE748 /* Configuration.swift in Sources */,
|
||||
7BF8D1FB2A70AF57005F1D6E /* SwiftUI+Theme.swift in Sources */,
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -661,3 +661,6 @@
|
|||
"onboarding_landing_title" = "Privacy in your pocket.";
|
||||
"onboarding_landing_register_button_title" = "Create account";
|
||||
"onboarding_landing_restore_button_title" = "I have an account";
|
||||
"onboarding_T&C" = "By using this service, you agree to our %@ and %@";
|
||||
"terms_of_service" = "Terms of Service";
|
||||
"privacy_policy" = "Privacy Policy";
|
||||
|
|
|
@ -40,7 +40,7 @@ struct LandingView: View {
|
|||
height: 40,
|
||||
alignment: .center
|
||||
)
|
||||
.background(ThemeManager.currentTheme.colorSwiftUI(for: .sessionButton_filledBackground))
|
||||
.backgroundColor(themeColor: .sessionButton_filledBackground)
|
||||
.cornerRadius(20)
|
||||
}
|
||||
|
||||
|
@ -58,14 +58,27 @@ struct LandingView: View {
|
|||
)
|
||||
.overlay(
|
||||
Capsule()
|
||||
.stroke(ThemeManager.currentTheme.colorSwiftUI(for: .sessionButton_border)!)
|
||||
.stroke(themeColor: .sessionButton_border)
|
||||
)
|
||||
}
|
||||
|
||||
Button {
|
||||
|
||||
} label: {
|
||||
Text("")
|
||||
let attributedText: NSAttributedString = {
|
||||
let text = String(format: "onboarding_T&C".localized(), "terms_of_service".localized(), "privacy_policy".localized())
|
||||
let result = NSMutableAttributedString(
|
||||
string: text,
|
||||
attributes: [ .font : UIFont.systemFont(ofSize: Values.verySmallFontSize)]
|
||||
)
|
||||
result.addAttribute(.font, value: UIFont.boldSystemFont(ofSize: Values.verySmallFontSize), range: (text as NSString).range(of: "terms_of_service".localized()))
|
||||
result.addAttribute(.font, value: UIFont.boldSystemFont(ofSize: Values.verySmallFontSize), range: (text as NSString).range(of: "privacy_policy".localized()))
|
||||
|
||||
return result
|
||||
}()
|
||||
AttributedText(attributedText)
|
||||
.foregroundColor(themeColor: .textPrimary)
|
||||
.frame(width: 262)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,4 +56,27 @@ public class SessionHostingViewController<Content>: UIHostingController<Content>
|
|||
|
||||
navigationItem.titleView = container
|
||||
}
|
||||
|
||||
internal func setUpNavBarSessionHeading() {
|
||||
let headingImageView = UIImageView(
|
||||
image: UIImage(named: "SessionHeading")?
|
||||
.withRenderingMode(.alwaysTemplate)
|
||||
)
|
||||
headingImageView.themeTintColor = .textPrimary
|
||||
headingImageView.contentMode = .scaleAspectFit
|
||||
headingImageView.set(.width, to: 150)
|
||||
headingImageView.set(.height, to: Values.mediumFontSize)
|
||||
|
||||
navigationItem.titleView = headingImageView
|
||||
}
|
||||
|
||||
internal func setUpNavBarSessionIcon() {
|
||||
let logoImageView = UIImageView()
|
||||
logoImageView.image = #imageLiteral(resourceName: "SessionGreen32")
|
||||
logoImageView.contentMode = .scaleAspectFit
|
||||
logoImageView.set(.width, to: 32)
|
||||
logoImageView.set(.height, to: 32)
|
||||
|
||||
navigationItem.titleView = logoImageView
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct AttributedTextBlock {
|
||||
let content: String
|
||||
let font: Font?
|
||||
let color: Color?
|
||||
}
|
||||
|
||||
public struct AttributedText: View {
|
||||
var attributedText: NSAttributedString?
|
||||
|
||||
private var descriptions: [AttributedTextBlock] = []
|
||||
|
||||
public init(_ attributedText: NSAttributedString?) {
|
||||
self.attributedText = attributedText
|
||||
|
||||
self.extractDescriptions()
|
||||
}
|
||||
|
||||
private mutating func extractDescriptions() {
|
||||
if let text = attributedText {
|
||||
text.enumerateAttributes(in: NSMakeRange(0, text.length), options: [], using: { (attribute, range, stop) in
|
||||
let substring = (text.string as NSString).substring(with: range)
|
||||
let font = (attribute[.font] as? UIFont).map { Font($0) }
|
||||
let color = (attribute[.foregroundColor] as? UIColor).map { Color($0) }
|
||||
descriptions.append(AttributedTextBlock(content: substring,
|
||||
font: font,
|
||||
color: color))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
let _ = print(descriptions)
|
||||
descriptions.map { description in
|
||||
var text: Text = Text(description.content)
|
||||
if let font: Font = description.font { text = text.font(font) }
|
||||
if let color: Color = description.color { text = text.foregroundColor(color) }
|
||||
return text
|
||||
}.reduce(Text("")) { (result, text) in
|
||||
result + text
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,12 @@ public extension View {
|
|||
ThemeManager.currentTheme.colorSwiftUI(for: themeColor)
|
||||
)
|
||||
}
|
||||
|
||||
func backgroundColor(themeColor: ThemeValue) -> some View {
|
||||
return self.background(
|
||||
ThemeManager.currentTheme.colorSwiftUI(for: themeColor)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public extension Shape {
|
||||
|
@ -16,4 +22,10 @@ public extension Shape {
|
|||
ThemeManager.currentTheme.colorSwiftUI(for: themeColor) ?? Color.primary
|
||||
)
|
||||
}
|
||||
|
||||
func stroke(themeColor: ThemeValue) -> some View {
|
||||
return self.stroke(
|
||||
ThemeManager.currentTheme.colorSwiftUI(for: themeColor) ?? Color.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue