mirror of
https://github.com/narrrl/proton-stream.git
synced 2026-11-03 16:41:26 +01:00
feat(app,android,ios): display type, artwork fade-in, shimmer, lifting tiles and paged shelves
A first pass at making the three clients look like a streaming app rather than a file browser, with no new data behind it. - Type: a Hero rung (34) set in Inter Display Bold, the optical size Inter draws for large text, for the banner's name and a title page's name where no logo stands in. Desktop `Role::Hero` and `theme::display`; Android and iOS `displayLarge`, at a tighter 1.1 leading. The font has its private use mappings stripped like the other two cuts. - Artwork fades in over its skeleton on Android and iOS, as it already did on desktop cards; art already decoded draws at once. Desktop episode stills and logos fade in too. - Skeletons shimmer: a soft diagonal highlight instead of a pulse. - Desktop tiles lift towards the viewer under the pointer, capped so a lifted tile never reaches its neighbour, and keyboard focus gets a ring of its own. - Desktop shelves share one `ui::shelf`: edges fade into the page and, under the pointer, round buttons page the row along. - Genres are chips on Android and iOS; quality (4K, HDR, 10-bit, Dual audio) moves out of the facts line into small outlined marks on all three. - Desktop title page and hero buttons use a tonal style beside the accent one, and the player's top bar a dark glass style, instead of egui's stock buttons. Episode numbers leave monospace for the type ramp. - The phone players' top and bottom bars are gradients rather than flat bands, and a double-tap seek is felt as well as seen.
This commit is contained in:
1 parent
3ebfd1a57b
commit
255e463fc8
33 files changed
+886
-290
No files matched your search
@@ -123,7 +123,7 @@ struct PlayerView: View {
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
.padding(.trailing, 16)
|
||||
.padding(.bottom, showControls ? 132 : 24)
|
||||
.padding(.bottom, showControls ? 160 : 24)
|
||||
|
||||
// Only while nothing else explains the still picture: an error
|
||||
// is the more useful thing to say.
|
||||
@@ -224,8 +224,15 @@ struct PlayerView: View {
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 4)
|
||||
.background(scheme.scrim.opacity(0.45).ignoresSafeArea(edges: [.top, .horizontal]))
|
||||
.padding(.top, 4)
|
||||
.padding(.bottom, 28)
|
||||
// A gradient rather than a band: dark where the text is, and gone by
|
||||
// the time it reaches the picture. Black whatever the theme, since
|
||||
// what is under it is a video frame.
|
||||
.background(
|
||||
LinearGradient(colors: [.black.opacity(0.75), .clear], startPoint: .top, endPoint: .bottom)
|
||||
.ignoresSafeArea(edges: [.top, .horizontal])
|
||||
)
|
||||
}
|
||||
|
||||
/// Show or hide the controls; shown and playing, they hide themselves.
|
||||
@@ -242,6 +249,8 @@ struct PlayerView: View {
|
||||
private func doubleTap(at x: CGFloat, width: CGFloat) {
|
||||
let third = width / 3
|
||||
let seconds = x < third ? -doubleTapSeconds : x > width - third ? doubleTapSeconds : 0
|
||||
// Felt as well as seen: the bubble is under the thumb that asked for it.
|
||||
UIImpactFeedbackGenerator(style: .light).impactOccurred()
|
||||
if seconds == 0 {
|
||||
host.setPaused(!player.paused)
|
||||
} else {
|
||||
@@ -355,8 +364,12 @@ private struct PlayerControls: View {
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 4)
|
||||
.background(scheme.scrim.opacity(0.68).ignoresSafeArea(edges: [.bottom, .horizontal]))
|
||||
.padding(.top, 32)
|
||||
.padding(.bottom, 4)
|
||||
.background(
|
||||
LinearGradient(colors: [.clear, .black.opacity(0.85)], startPoint: .top, endPoint: .bottom)
|
||||
.ignoresSafeArea(edges: [.bottom, .horizontal])
|
||||
)
|
||||
}
|
||||
|
||||
private func toggleMute() {
|
||||
|
||||
Reference in new issue
Block a user