Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
44 changes: 44 additions & 0 deletions MC1/Extensions/View+ScrollRevealTitle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import SwiftUI

extension View {
/// Leaves the navigation bar title empty while the header is on screen, then fades
/// in `title` (the entity name) once the user scrolls past `revealAfter` points.
/// Pass the header's measured height (see `scrollRevealHeaderHeight`) so the reveal
/// tracks the real header size and adapts to Dynamic Type.
/// Pairs with `.navigationBarTitleDisplayMode(.inline)`.
func scrollRevealNavigationTitle(_ title: String, revealAfter: CGFloat = 150) -> some View {
modifier(ScrollRevealNavigationTitle(title: title, revealAfter: revealAfter))
}

/// Reports the measured height of the scroll-reveal header into `height`, so the
/// title reveals based on the header's real (Dynamic Type-aware) size rather than a
/// fixed threshold. Attach to the header content, then feed `height` to
/// `scrollRevealNavigationTitle(_:revealAfter:)`.
func scrollRevealHeaderHeight(into height: Binding<CGFloat>) -> some View {
onGeometryChange(for: CGFloat.self) { $0.size.height } action: { height.wrappedValue = $0 }
}
}

private struct ScrollRevealNavigationTitle: ViewModifier {
let title: String
let revealAfter: CGFloat

@State private var isRevealed = false

func body(content: Content) -> some View {
content
.onScrollGeometryChange(for: Bool.self) { geometry in
geometry.contentOffset.y > revealAfter
} action: { _, revealed in
guard revealed != isRevealed else { return }
withAnimation(.easeInOut(duration: 0.2)) { isRevealed = revealed }
}
.toolbar {
ToolbarItem(placement: .principal) {
Text(title)
.font(.headline)
.opacity(isRevealed ? 1 : 0)
}
}
}
}
26 changes: 19 additions & 7 deletions MC1/Views/Chats/Room/RoomInfoSheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct RoomInfoSheet: View {
@State private var favoriteTask: Task<Void, Never>?
@State private var showTelemetry = false
@State private var showSettings = false
@State private var headerHeight: CGFloat = 150

init(session: RemoteNodeSessionDTO) {
self.session = session
Expand All @@ -27,17 +28,27 @@ struct RoomInfoSheet: View {
NavigationStack {
List {
Section {
HStack {
Spacer()
NodeAvatar(publicKey: session.publicKey, role: .roomServer, size: 80)
Spacer()
VStack(spacing: 12) {
NodeAvatar(publicKey: session.publicKey, role: .roomServer, size: 150)

VStack(spacing: 4) {
Text(session.name)
.font(.title2)
.bold()

Text(L10n.RemoteNodes.RemoteNodes.Auth.typeRoom)
.font(.subheadline)
.foregroundStyle(.secondary)
}
}
.frame(maxWidth: .infinity)
.scrollRevealHeaderHeight(into: $headerHeight)
.listRowBackground(Color.clear)
}

ConversationQuickActionsSection(
notificationLevel: $notificationLevel,
isFavorite: $isFavorite,
Comment thread
bwees marked this conversation as resolved.
notificationLevel: $notificationLevel,
availableLevels: NotificationLevel.roomLevels
)
.onChange(of: notificationLevel) { _, newValue in
Expand Down Expand Up @@ -102,10 +113,11 @@ struct RoomInfoSheet: View {
.themedRowBackground(theme)
}
.themedCanvas(theme)
.navigationTitle(Strings.infoTitle)
.navigationBarTitleDisplayMode(.inline)
.scrollRevealNavigationTitle(session.name, revealAfter: headerHeight)
.contentMargins(.top, 0, for: .scrollContent)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
ToolbarItem(placement: .confirmationAction) {
Button(L10n.Localizable.Common.done) { dismiss() }
}
}
Expand Down
36 changes: 17 additions & 19 deletions MC1/Views/Chats/Sheets/ChannelInfoSheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct ChannelInfoSheet: View {
@State private var discoveredNewRegions: [String] = []
@State private var showingDiscoveryResults = false
@State private var selectedFloodScope: ChannelFloodScope
@State private var headerHeight: CGFloat = 150

init(channel: ChannelDTO, onClearMessages: @escaping () -> Void, onDelete: @escaping () -> Void) {
self.channel = channel
Expand All @@ -48,12 +49,12 @@ struct ChannelInfoSheet: View {
NavigationStack {
Form {
// Channel Header Section
ChannelInfoHeaderSection(channel: channel)
ChannelInfoHeaderSection(channel: channel, measuredHeight: $headerHeight)

// Quick Actions Section
ConversationQuickActionsSection(
notificationLevel: $notificationLevel,
isFavorite: $isFavorite,
notificationLevel: $notificationLevel,
availableLevels: NotificationLevel.channelLevels
)
.onChange(of: notificationLevel) { _, newValue in
Expand Down Expand Up @@ -123,10 +124,11 @@ struct ChannelInfoSheet: View {
)
}
.themedCanvas(theme)
.navigationTitle(L10n.Chats.Chats.ChannelInfo.title)
.navigationBarTitleDisplayMode(.inline)
.scrollRevealNavigationTitle(channel.displayName, revealAfter: headerHeight)
.contentMargins(.top, 0, for: .scrollContent)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
ToolbarItem(placement: .confirmationAction) {
Button(L10n.Chats.Chats.Common.done) {
dismiss()
}
Expand Down Expand Up @@ -354,6 +356,7 @@ struct ChannelInfoSheet: View {

private struct ChannelInfoHeaderSection: View {
let channel: ChannelDTO
@Binding var measuredHeight: CGFloat

private var channelTypeLabel: String {
if channel.isPublicChannel {
Expand All @@ -367,11 +370,10 @@ private struct ChannelInfoHeaderSection: View {

var body: some View {
Section {
HStack {
Spacer()
VStack(spacing: 12) {
ChannelAvatar(channel: channel, size: 80)
VStack(spacing: 12) {
ChannelAvatar(channel: channel, size: 150)

VStack(spacing: 4) {
Text(channel.displayName)
.font(.title2)
.bold()
Expand All @@ -380,8 +382,9 @@ private struct ChannelInfoHeaderSection: View {
.font(.subheadline)
.foregroundStyle(.secondary)
}
Spacer()
}
.frame(maxWidth: .infinity)
.scrollRevealHeaderHeight(into: $measuredHeight)
.listRowBackground(Color.clear)
}
}
Expand Down Expand Up @@ -487,33 +490,28 @@ private struct ChannelInfoActionsSection: View {

var body: some View {
Section {
Button {
Button(role: .destructive) {
showingClearMessagesConfirmation = true
} label: {
HStack {
Spacer()
Label(L10n.Chats.Chats.ChannelInfo.clearMessagesButton, systemImage: "xmark.circle")
if isClearingMessages {
Spacer()
ProgressView()
} else {
Label(L10n.Chats.Chats.ChannelInfo.clearMessagesButton, systemImage: "xmark.circle")
}
Spacer()
}
}
.disabled(isActionInProgress)
.alignmentGuide(.listRowSeparatorLeading) { _ in 0 }

Button(role: .destructive) {
showingDeleteConfirmation = true
} label: {
HStack {
Spacer()
Label(L10n.Chats.Chats.ChannelInfo.deleteButton, systemImage: "trash")
if isDeleting {
Spacer()
ProgressView()
} else {
Label(L10n.Chats.Chats.ChannelInfo.deleteButton, systemImage: "trash")
}
Spacer()
}
}
.disabled(isActionInProgress)
Expand Down
14 changes: 7 additions & 7 deletions MC1/Views/Components/ConversationQuickActionsSection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,28 @@ import SwiftUI

struct ConversationQuickActionsSection: View {
@Environment(\.appTheme) private var theme
@Binding var notificationLevel: NotificationLevel
@Binding var isFavorite: Bool
@Binding var notificationLevel: NotificationLevel
let availableLevels: [NotificationLevel]

init(
notificationLevel: Binding<NotificationLevel>,
isFavorite: Binding<Bool>,
notificationLevel: Binding<NotificationLevel>,
availableLevels: [NotificationLevel] = NotificationLevel.allCases
) {
_notificationLevel = notificationLevel
_isFavorite = isFavorite
_notificationLevel = notificationLevel
self.availableLevels = availableLevels
}

var body: some View {
Section {
VStack(spacing: 16) {
NotificationLevelPicker(selection: $notificationLevel, availableLevels: availableLevels)
NotificationLevelPicker(selection: $notificationLevel, availableLevels: availableLevels)
.listRowInsets(EdgeInsets(top: 12, leading: 16, bottom: 12, trailing: 16))

FavoriteToggleRow(isFavorite: $isFavorite)
Toggle(isOn: $isFavorite) {
Label(L10n.Chats.Chats.Action.favorite, systemImage: "star")
}
.listRowInsets(EdgeInsets(top: 12, leading: 16, bottom: 12, trailing: 16))
}
.themedRowBackground(theme)
}
Expand Down
22 changes: 0 additions & 22 deletions MC1/Views/Components/FavoriteToggleRow.swift

This file was deleted.

Loading
Loading