Skip to content

Commit 1b8a646

Browse files
committed
Merge branch 'onboarding' into develop
# Conflicts: # MacMagazine/MacMagazine/MainApp/MacMagazineApp.swift
2 parents 9907ba6 + 1873752 commit 1b8a646

36 files changed

Lines changed: 1992 additions & 37 deletions

MacMagazine/Features/MMLiveLibrary/Sources/MMLiveLibrary/Services/PushNotification.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ final class PushNotification: NSObject, PushNotificationProtocol {
1818
if settings.authorizationStatus == .authorized {
1919
process(event: event)
2020
} else {
21-
guard let granted = try? await center.requestAuthorization(options: [.alert, .sound, .badge]),
22-
granted else { return }
23-
process(event: event)
21+
// guard let granted = try? await center.requestAuthorization(options: [.alert, .sound, .badge]),
22+
// granted else { return }
23+
// process(event: event)
2424
}
2525
}
2626
}

MacMagazine/Features/MacMagazineLibrary/Sources/MacMagazineLibrary/AnalyticsConstants.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ public enum AnalyticsConstants {
5353
// Other
5454
case loginPatroes
5555

56+
// Onboarding
57+
case onboardingWelcome
58+
case onboardingFeatures
59+
case onboardingPermissions
60+
5661
// Widget
5762
case widget(String)
5863

@@ -83,6 +88,11 @@ public enum AnalyticsConstants {
8388
// Other
8489
case .loginPatroes: "Login para patrões"
8590

91+
// Onboarding
92+
case .onboardingWelcome: "Onboarding > Welcome"
93+
case .onboardingFeatures: "Onboarding > Features"
94+
case .onboardingPermissions: "Onboarding > Permissions"
95+
8696
// Widget
8797
case let .widget(type): "Widget \(type)"
8898
}
@@ -154,6 +164,21 @@ public enum AnalyticsConstants {
154164
case termsConditions
155165
case privacyPolicy
156166

167+
// MARK: Onboarding
168+
case onboardingWelcomeSkip
169+
case onboardingWelcomeContinue
170+
case onboardingFeaturesSkip
171+
case onboardingFeaturesContinue
172+
case onboardingFeaturePage(Int)
173+
case onboardingPushSkip
174+
case onboardingPushContinue
175+
case onboardingPushAccepted
176+
case onboardingPushDenied
177+
case onboardingATTContinue
178+
case onboardingATTAccepted
179+
case onboardingATTDenied
180+
case onboardingComplete
181+
157182
public var id: String {
158183
switch self {
159184
// Podcast Player - Full Player
@@ -214,6 +239,21 @@ public enum AnalyticsConstants {
214239
case .reportProblem: return "report_problem"
215240
case .termsConditions: return "terms_conditions"
216241
case .privacyPolicy: return "privacy_policy"
242+
243+
// Onboarding
244+
case .onboardingWelcomeSkip: return "onboarding_welcome_skip"
245+
case .onboardingWelcomeContinue: return "onboarding_welcome_continue"
246+
case .onboardingFeaturesSkip: return "onboarding_features_skip"
247+
case .onboardingFeaturesContinue: return "onboarding_features_continue"
248+
case .onboardingFeaturePage(let page): return "onboarding_feature_page_\(page)"
249+
case .onboardingPushSkip: return "onboarding_push_skip"
250+
case .onboardingPushContinue: return "onboarding_push_continue"
251+
case .onboardingPushAccepted: return "onboarding_push_accepted"
252+
case .onboardingPushDenied: return "onboarding_push_denied"
253+
case .onboardingATTContinue: return "onboarding_att_continue"
254+
case .onboardingATTAccepted: return "onboarding_att_accepted"
255+
case .onboardingATTDenied: return "onboarding_att_denied"
256+
case .onboardingComplete: return "onboarding_complete"
217257
}
218258
}
219259
}

MacMagazine/Features/OnboardingLibrary/Package.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,18 @@ let package = Package(
1111
],
1212
dependencies: [
1313
.package(name: "MacMagazineLibrary", path: "../MacMagazineLibrary"),
14+
.package(name: "MacMagazineUILibrary", path: "../MacMagazineUILibrary"),
1415
.package(url: "https://github.com/cassio-rossi/Libraries.git", branch: "main")
1516
],
1617
targets: [
1718
.target(name: "OnboardingLibrary",
1819
dependencies: [
1920
"MacMagazineLibrary",
20-
.product(name: "Storage", package: "Libraries")
21-
])
21+
"MacMagazineUILibrary",
22+
.product(name: "Storage", package: "Libraries"),
23+
.product(name: "Analytics", package: "Libraries"),
24+
.product(name: "UIComponents", package: "Libraries")
25+
],
26+
resources: [.process("Resources")])
2227
]
2328
)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import SwiftUI
2+
3+
public extension Array {
4+
func chunked(into size: Int) -> [[Element]] {
5+
guard size > 0 else { return [self] }
6+
return stride(from: 0, to: count, by: size).map { index in
7+
Array(self[index..<Swift.min(index + size, count)])
8+
}
9+
}
10+
11+
subscript(safe index: Int) -> Element? {
12+
guard indices.contains(index) else { return nil }
13+
return self[index]
14+
}
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import SwiftUI
2+
3+
// MARK: - Landscape Detection Extension
4+
5+
public extension EnvironmentValues {
6+
var isLandscape: Bool {
7+
verticalSizeClass == .compact
8+
}
9+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import SwiftUI
2+
3+
public extension View {
4+
5+
@ViewBuilder
6+
func blurSlide(_ show: Bool) -> some View {
7+
self
8+
.compositingGroup()
9+
.blur(radius: show ? 0 : 10)
10+
.opacity(show ? 1 : 0)
11+
.offset(y: show ? 0 : 100)
12+
}
13+
14+
@ViewBuilder
15+
func setUpOnBoarding() -> some View {
16+
#if os(macOS)
17+
self
18+
.padding(.horizontal, 20)
19+
.frame(minHeight: 600)
20+
#else
21+
if UIDevice.current.userInterfaceIdiom == .pad {
22+
self
23+
.presentationSizing(.fitted)
24+
.padding(.horizontal, 25)
25+
} else {
26+
self
27+
}
28+
#endif
29+
}
30+
31+
/// Helper para acessar isLandscape dentro de uma View
32+
func readIsLandscape(_ binding: Binding<Bool>) -> some View {
33+
self.modifier(LandscapeReaderModifier(isLandscape: binding))
34+
}
35+
36+
var isMac: Bool {
37+
#if os(macOS)
38+
return true
39+
#else
40+
return false
41+
#endif
42+
}
43+
44+
/// Aplica animação de entrada padrão do onboarding
45+
/// - Parameters:
46+
/// - animateIn: Estado de animação
47+
/// - delay: Delay da animação
48+
/// - reduceMotion: Se deve respeitar preferência de reduzir movimento
49+
func onboardingAnimateIn(
50+
_ animateIn: Bool,
51+
delay: Double = 0,
52+
reduceMotion: Bool = false
53+
) -> some View {
54+
self
55+
.opacity(animateIn ? 1 : 0)
56+
.offset(y: animateIn ? 0 : (reduceMotion ? 0 : 20))
57+
.animation(
58+
reduceMotion ? nil : .easeOut(duration: 0.5).delay(delay),
59+
value: animateIn
60+
)
61+
}
62+
63+
func onboardingFade(
64+
_ isVisible: Bool,
65+
delay: Double = 0,
66+
duration: Double = 0.6
67+
) -> some View {
68+
modifier(OnboardingFadeModifier(isVisible: isVisible, delay: delay, duration: duration))
69+
}
70+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import SwiftUI
2+
3+
public struct OnBoardingFeature: Identifiable {
4+
public var id: String = UUID().uuidString
5+
let symbol: String
6+
let title: String
7+
let subTitle: String
8+
}
9+
10+
@MainActor
11+
public extension OnBoardingFeature {
12+
static let allCards: [OnBoardingFeature] = [
13+
OnBoardingFeature(
14+
symbol: "sparkles",
15+
title: "Nova interface",
16+
subTitle: "Liquid Glass. Rápido e fácil de usar."
17+
),
18+
OnBoardingFeature(
19+
symbol: "ipad.and.iphone",
20+
title: "iPhone e iPad",
21+
subTitle: "Experiências diferentes, pensadas para cada dispositivo."
22+
),
23+
OnBoardingFeature(
24+
symbol: "apple.podcasts.pages",
25+
title: "Experiência em podcasts",
26+
subTitle: "Controle completo do player. Capítulos."
27+
),
28+
OnBoardingFeature(
29+
symbol: "photo.on.rectangle.angled",
30+
title: "Instagram",
31+
subTitle: "Nova categoria dedicada ao Instagram."
32+
),
33+
OnBoardingFeature(
34+
symbol: "folder.fill",
35+
title: "Categorias de posts",
36+
subTitle: "Explore conteúdos organizados por categorias."
37+
),
38+
OnBoardingFeature(
39+
symbol: "slider.horizontal.3",
40+
title: "App personalizável",
41+
subTitle: "Deixe o app com a sua cara, com ajustes personalizados."
42+
),
43+
OnBoardingFeature(
44+
symbol: "icloud.fill",
45+
title: "Sincronização com iCloud",
46+
subTitle: "Suas preferências sincronizadas em todos os dispositivos."
47+
),
48+
OnBoardingFeature(
49+
symbol: "applewatch",
50+
title: "Novo app para Apple Watch",
51+
subTitle: "Fique informado direto no pulso."
52+
),
53+
OnBoardingFeature(
54+
symbol: "square.grid.2x2.fill",
55+
title: "Nova interface de widgets",
56+
subTitle: "Widgets lindos com design Liquid Glass."
57+
),
58+
OnBoardingFeature(
59+
symbol: "gift.fill",
60+
title: "Mais uma novidade",
61+
subTitle: "Descubra recursos escondidos por todo o app."
62+
),
63+
OnBoardingFeature(
64+
symbol: "desktopcomputer",
65+
title: "App para macOS",
66+
subTitle: "Aplicativo completo para Mac, pensado para o desktop."
67+
)
68+
]
69+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"info" : {
3+
"author" : "xcode",
4+
"version" : 1
5+
}
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "alternativa_sem_fundo.png",
5+
"idiom" : "universal"
6+
}
7+
],
8+
"info" : {
9+
"author" : "xcode",
10+
"version" : 1
11+
}
12+
}
Loading

0 commit comments

Comments
 (0)