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

Observation #200

Merged
merged 65 commits into from
Apr 9, 2024
Merged
Changes from 1 commit
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
c8ded4e
Bump
stephencelis Dec 7, 2023
bf0c97a
wip
stephencelis Dec 7, 2023
84fb895
wip
stephencelis Dec 7, 2023
7a12f8b
wip
stephencelis Dec 8, 2023
e67c0c9
wip
stephencelis Dec 8, 2023
5b24ecf
wip
stephencelis Dec 8, 2023
015932b
wip
stephencelis Dec 8, 2023
57d676d
wip
stephencelis Dec 8, 2023
816d53f
wip
stephencelis Dec 8, 2023
286618f
wip
stephencelis Dec 8, 2023
49df034
wip
stephencelis Dec 8, 2023
0c5270b
wip
stephencelis Dec 8, 2023
852d16c
wip
stephencelis Dec 8, 2023
39c9bb7
wip
stephencelis Dec 8, 2023
19c35f6
wip
stephencelis Dec 8, 2023
fda7be3
wip
stephencelis Dec 8, 2023
3e5a8aa
wip
stephencelis Dec 8, 2023
810fcf3
wip
stephencelis Dec 8, 2023
0932033
wip
stephencelis Dec 8, 2023
4db019c
wip
stephencelis Dec 8, 2023
7b9ae18
wip
stephencelis Dec 8, 2023
70b7e3b
wip
stephencelis Dec 8, 2023
d7da8fc
wip
stephencelis Dec 8, 2023
27e4812
wip
stephencelis Dec 8, 2023
efa9f2b
wip
stephencelis Dec 8, 2023
716bf9c
wip
stephencelis Dec 8, 2023
0aaa62e
wip
stephencelis Dec 8, 2023
7e009ff
wip
stephencelis Dec 8, 2023
de50bc5
wip
stephencelis Dec 8, 2023
319387e
wip
stephencelis Dec 8, 2023
c2f288f
wip
stephencelis Dec 8, 2023
be08617
wip
stephencelis Dec 8, 2023
8abe58f
wip
stephencelis Dec 8, 2023
4a1b154
Merge remote-tracking branch 'origin/main' into observation-beta
stephencelis Dec 8, 2023
f59b3de
wip
stephencelis Dec 8, 2023
e57166f
wip
stephencelis Dec 9, 2023
8a8ff1f
wip
stephencelis Dec 9, 2023
a34be6f
wip
stephencelis Dec 9, 2023
380ce12
wip
stephencelis Dec 9, 2023
eb75020
wip
stephencelis Dec 9, 2023
2fc8dc6
wip
stephencelis Dec 9, 2023
5233f32
wip
stephencelis Dec 9, 2023
cf5f10e
wip
stephencelis Dec 9, 2023
eab3475
wip
stephencelis Dec 9, 2023
2a30738
wip
stephencelis Dec 9, 2023
0740836
wip
stephencelis Dec 9, 2023
db145d3
wip
stephencelis Dec 9, 2023
fa6251d
wip
stephencelis Dec 9, 2023
fd47050
wip
stephencelis Dec 9, 2023
29fae99
Merge branch 'main' into observation-beta
stephencelis Jan 10, 2024
7199286
wip
stephencelis Jan 10, 2024
bc41412
wip
stephencelis Jan 25, 2024
cee0c1c
Merge remote-tracking branch 'origin/main' into observation-beta
stephencelis Jan 25, 2024
098df9f
wip
stephencelis Jan 25, 2024
03716cf
wip
stephencelis Jan 25, 2024
d39632d
Remove firstLaunchOnboarding (#198)
imjn Jan 25, 2024
07e5628
Merge remote-tracking branch 'origin/main' into observation-beta
mbrandonw Apr 7, 2024
beeda8f
use enum reducers
mbrandonw Apr 7, 2024
29d1884
fix some warnings
mbrandonw Apr 7, 2024
b93b94c
udpate last destination reducer
mbrandonw Apr 8, 2024
b9d6bed
ignore some errors
mbrandonw Apr 8, 2024
dae32ea
wip
mbrandonw Apr 9, 2024
ba30ab2
wip
stephencelis Apr 9, 2024
9af2a17
wip
stephencelis Apr 9, 2024
f68c1cd
wip
stephencelis Apr 9, 2024
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
Prev Previous commit
Next Next commit
wip
  • Loading branch information
stephencelis committed Dec 8, 2023
commit 70b7e3b6e2b913903ccb0db6544519aa29b4da1a
90 changes: 37 additions & 53 deletions Sources/TrailerFeature/Trailer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import UIApplicationClient

@Reducer
public struct Trailer {
@ObservableState
public struct State: Equatable {
var game: Game.State
@BindingState var nub: CubeSceneView.ViewState.NubState
@BindingState var opacity: Double
var nub: CubeSceneView.ViewState.NubState
var opacity: Double

public init(
game: Game.State,
Expand All @@ -25,7 +26,7 @@ public struct Trailer {
}

public init() {
self = .init(
self.init(
game: .init(
cubes: .trailer,
gameContext: .solo,
Expand Down Expand Up @@ -93,7 +94,7 @@ public struct Trailer {
await self.audioPlayer.play(.onboardingBgMusic)

// Fade the cube in after a second
await send(.set(\.$opacity, 1), animation: .easeInOut(duration: fadeInDuration))
await send(.set(\.opacity, 1), animation: .easeInOut(duration: fadeInDuration))
try await self.mainQueue.sleep(for: firstWordDelay)

// Play each word
Expand All @@ -105,7 +106,7 @@ public struct Trailer {
// Move the nub to the face being played
nub.location = .face(face)
await send(
.set(\.$nub, nub),
.set(\.nub, nub),
animateWithDuration: moveNubToFaceDuration,
options: .curveEaseInOut
)
Expand All @@ -120,22 +121,22 @@ public struct Trailer {
// Press the nub on the first character
nub.isPressed = true
if characterIndex == 0 {
await send(.set(\.$nub, nub), animateWithDuration: 0.3)
await send(.set(\.nub, nub), animateWithDuration: 0.3)
}
// Select the cube face
await send(.game(.tap(.began, face)), animation: .default)
}

// Release the nub when the last character is played
nub.isPressed = false
await send(.set(\.$nub, nub), animateWithDuration: 0.3)
await send(.set(\.nub, nub), animateWithDuration: 0.3)

// Move the nub to the submit button
try await self.mainQueue.sleep(for: .seconds(0.3))

nub.location = .submitButton
await send(
.set(\.$nub, nub),
.set(\.nub, nub),
animateWithDuration: moveNubToSubmitButtonDuration,
options: .curveEaseInOut
)
Expand All @@ -157,15 +158,15 @@ public struct Trailer {
group.addTask { [nub] in
var nub = nub
nub.isPressed = true
await send(.set(\.$nub, nub), animateWithDuration: 0.3)
await send(.set(\.nub, nub), animateWithDuration: 0.3)
}
group.addTask { [nub] in
var nub = nub
try await self.mainQueue.sleep(for: .seconds(0.2))
await send(.game(.submitButtonTapped(reaction: nil)))
try await self.mainQueue.sleep(for: .seconds(0.3))
nub.isPressed = false
await send(.set(\.$nub, nub), animateWithDuration: 0.3)
await send(.set(\.nub, nub), animateWithDuration: 0.3)
}
}
}
Expand All @@ -174,12 +175,12 @@ public struct Trailer {
try await self.mainQueue.sleep(for: .seconds(0.3))
nub.location = .offScreenBottom
await send(
.set(\.$nub, nub),
.set(\.nub, nub),
animateWithDuration: moveNubOffScreenDuration,
options: .curveEaseInOut
)

await send(.set(\.$opacity, 0), animation: .linear(duration: moveNubOffScreenDuration))
await send(.set(\.opacity, 0), animation: .linear(duration: moveNubOffScreenDuration))
}
}
}
Expand All @@ -188,36 +189,18 @@ public struct Trailer {

public struct TrailerView: View {
let store: StoreOf<Trailer>
@ObservedObject var viewStore: ViewStore<ViewState, Trailer.Action>
@Environment(\.deviceState) var deviceState

struct ViewState: Equatable {
let opacity: Double
let selectedWordHasAlreadyBeenPlayed: Bool
let selectedWordIsValid: Bool
let selectedWordScore: Int?
let selectedWordString: String

init(state: Trailer.State) {
self.opacity = state.opacity
self.selectedWordHasAlreadyBeenPlayed = state.game.selectedWordHasAlreadyBeenPlayed
self.selectedWordIsValid = state.game.selectedWordIsValid
self.selectedWordScore = self.selectedWordIsValid ? state.game.selectedWordScore : nil
self.selectedWordString = state.game.selectedWordString
}
}

public init(store: StoreOf<Trailer>) {
self.store = store
self.viewStore = ViewStore(self.store, observe: ViewState.init)
}

public var body: some View {
GeometryReader { proxy in
ZStack {
VStack {
if !self.viewStore.selectedWordString.isEmpty {
(Text(self.viewStore.selectedWordString)
if !store.game.selectedWordString.isEmpty {
(Text(store.game.selectedWordString)
+ self.scoreText
.baselineOffset(
(self.deviceState.idiom == .pad ? 2 : 1) * 16
Expand All @@ -232,19 +215,19 @@ public struct TrailerView: View {
.matterSemiBold,
size: (self.deviceState.idiom == .pad ? 2 : 1) * 32
)
.opacity(self.viewStore.selectedWordIsValid ? 1 : 0.5)
.opacity(store.game.selectedWordIsValid ? 1 : 0.5)
.allowsTightening(true)
.minimumScaleFactor(0.2)
.lineLimit(1)
.transition(.opacity)
.animation(nil, value: self.viewStore.selectedWordString)
.animation(nil, value: store.game.selectedWordString)
}

Spacer()

if !self.viewStore.selectedWordString.isEmpty {
if !store.game.selectedWordString.isEmpty {
WordSubmitButton(
store: self.store.scope(
store: store.scope(
state: \.game.wordSubmitButtonFeature,
action: \.game.wordSubmitButton
)
Expand All @@ -259,13 +242,13 @@ public struct TrailerView: View {

WordListView(
isLeftToRight: true,
store: self.store.scope(state: \.game, action: \.game)
store: store.scope(state: \.game, action: \.game)
)
}
.adaptivePadding(.top, .grid(18))
.adaptivePadding(.bottom, .grid(2))

CubeView(store: self.store.scope(state: \.cubeScene, action: \.game.cubeScene))
CubeView(store: store.scope(state: \.cubeScene, action: \.game.cubeScene))
.adaptivePadding(
self.deviceState.idiom == .pad ? .horizontal : [],
.grid(30)
Expand All @@ -274,31 +257,32 @@ public struct TrailerView: View {
.background(
BloomBackground(
size: proxy.size,
store: self.store
.scope(
state: {
BloomBackground.ViewState(
bloomCount: $0.game.selectedWord.count,
word: $0.game.selectedWordString
)
},
action: absurd
)
store: store.scope(
state: {
BloomBackground.ViewState(
bloomCount: $0.game.selectedWord.count,
word: $0.game.selectedWordString
)
},
action: absurd
)
)
)
}
.padding(
self.deviceState.idiom == .pad ? .vertical : [],
.grid(15)
)
.opacity(self.viewStore.opacity)
.task { await self.viewStore.send(.task).finish() }
.opacity(store.opacity)
.task { await store.send(.task).finish() }
}

var scoreText: Text {
self.viewStore.selectedWordScore.map {
Text(" \($0)")
} ?? Text("")
if store.game.selectedWordIsValid {
return Text(" \(store.game.selectedWordScore)")
} else {
return Text(verbatim: "")
}
}
}

Expand Down