Reorganize share UI with Easy Share on top
Move Easy Share (.casera file) section above Share Code section in the invite users dialog. Both platforms now have consistent UI with both buttons using the same filled button style. iOS changes: - Move share functionality into ManageUsersView - Remove share button from ResidenceDetailView toolbar - Redesign ShareCodeCard with Easy Share on top Android changes: - Update ManageUsersDialog with matching layout - Connect share package callback to existing share function 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ struct ManageUsersView: View {
|
||||
let residenceName: String
|
||||
let isPrimaryOwner: Bool
|
||||
let residenceOwnerId: Int32
|
||||
let residence: ResidenceResponse?
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
@State private var users: [ResidenceUserResponse] = []
|
||||
@@ -14,6 +15,8 @@ struct ManageUsersView: View {
|
||||
@State private var isLoading = true
|
||||
@State private var errorMessage: String?
|
||||
@State private var isGeneratingCode = false
|
||||
@State private var shareFileURL: URL?
|
||||
@StateObject private var sharingManager = ResidenceSharingManager.shared
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
@@ -36,7 +39,9 @@ struct ManageUsersView: View {
|
||||
shareCode: shareCode,
|
||||
residenceName: residenceName,
|
||||
isGeneratingCode: isGeneratingCode,
|
||||
onGenerateCode: generateShareCode
|
||||
isGeneratingPackage: sharingManager.isGeneratingPackage,
|
||||
onGenerateCode: generateShareCode,
|
||||
onEasyShare: easyShare
|
||||
)
|
||||
.padding(.horizontal)
|
||||
.padding(.top)
|
||||
@@ -82,6 +87,32 @@ struct ManageUsersView: View {
|
||||
shareCode = nil
|
||||
loadUsers()
|
||||
}
|
||||
.sheet(isPresented: Binding(
|
||||
get: { shareFileURL != nil },
|
||||
set: { if !$0 { shareFileURL = nil } }
|
||||
)) {
|
||||
if let url = shareFileURL {
|
||||
ShareSheet(activityItems: [url])
|
||||
}
|
||||
}
|
||||
.alert("Error", isPresented: Binding(
|
||||
get: { sharingManager.errorMessage != nil },
|
||||
set: { if !$0 { sharingManager.errorMessage = nil } }
|
||||
)) {
|
||||
Button("OK", role: .cancel) {}
|
||||
} message: {
|
||||
Text(sharingManager.errorMessage ?? "Failed to create share link.")
|
||||
}
|
||||
}
|
||||
|
||||
private func easyShare() {
|
||||
guard let residence = residence else { return }
|
||||
|
||||
Task {
|
||||
if let url = await sharingManager.createShareableFile(residence: residence) {
|
||||
shareFileURL = url
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func loadUsers() {
|
||||
@@ -196,5 +227,5 @@ struct ManageUsersView: View {
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ManageUsersView(residenceId: 1, residenceName: "My Home", isPrimaryOwner: true, residenceOwnerId: 1)
|
||||
ManageUsersView(residenceId: 1, residenceName: "My Home", isPrimaryOwner: true, residenceOwnerId: 1, residence: nil)
|
||||
}
|
||||
|
||||
@@ -33,10 +33,7 @@ struct ResidenceDetailView: View {
|
||||
@State private var isDeleting = false
|
||||
@State private var showingUpgradePrompt = false
|
||||
@State private var upgradeTriggerKey = ""
|
||||
@State private var showShareSheet = false
|
||||
@State private var shareFileURL: URL?
|
||||
@StateObject private var subscriptionCache = SubscriptionCacheWrapper.shared
|
||||
@StateObject private var sharingManager = ResidenceSharingManager.shared
|
||||
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
@@ -125,7 +122,8 @@ struct ResidenceDetailView: View {
|
||||
residenceId: residence.id,
|
||||
residenceName: residence.name,
|
||||
isPrimaryOwner: isCurrentUserOwner(of: residence),
|
||||
residenceOwnerId: residence.ownerId
|
||||
residenceOwnerId: residence.ownerId,
|
||||
residence: residence
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -150,22 +148,6 @@ struct ResidenceDetailView: View {
|
||||
.sheet(isPresented: $showingUpgradePrompt) {
|
||||
UpgradePromptView(triggerKey: upgradeTriggerKey.isEmpty ? "add_11th_task" : upgradeTriggerKey, isPresented: $showingUpgradePrompt)
|
||||
}
|
||||
.sheet(isPresented: $showShareSheet) {
|
||||
if let url = shareFileURL {
|
||||
ShareSheet(activityItems: [url])
|
||||
}
|
||||
}
|
||||
// Share error alert
|
||||
.alert("Share Failed", isPresented: .init(
|
||||
get: { sharingManager.errorMessage != nil },
|
||||
set: { if !$0 { sharingManager.resetState() } }
|
||||
)) {
|
||||
Button("OK") {
|
||||
sharingManager.resetState()
|
||||
}
|
||||
} message: {
|
||||
Text(sharingManager.errorMessage ?? "Failed to create share link.")
|
||||
}
|
||||
|
||||
// MARK: onChange & lifecycle
|
||||
.onChange(of: viewModel.reportMessage) { message in
|
||||
@@ -357,26 +339,7 @@ private extension ResidenceDetailView {
|
||||
.disabled(viewModel.isGeneratingReport)
|
||||
}
|
||||
|
||||
// Share Residence button (owner only)
|
||||
if let residence = viewModel.selectedResidence, isCurrentUserOwner(of: residence) {
|
||||
Button {
|
||||
if subscriptionCache.canShareResidence() {
|
||||
shareResidence(residence)
|
||||
} else {
|
||||
upgradeTriggerKey = "share_residence"
|
||||
showingUpgradePrompt = true
|
||||
}
|
||||
} label: {
|
||||
if sharingManager.isGeneratingPackage {
|
||||
ProgressView()
|
||||
} else {
|
||||
Image(systemName: "square.and.arrow.up")
|
||||
}
|
||||
}
|
||||
.disabled(sharingManager.isGeneratingPackage)
|
||||
}
|
||||
|
||||
// Manage Users button (owner only)
|
||||
// Manage Users button (owner only) - includes share code generation and easy share
|
||||
if let residence = viewModel.selectedResidence, isCurrentUserOwner(of: residence) {
|
||||
Button {
|
||||
if subscriptionCache.canShareResidence() {
|
||||
@@ -415,15 +378,6 @@ private extension ResidenceDetailView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func shareResidence(_ residence: ResidenceResponse) {
|
||||
Task {
|
||||
if let url = await sharingManager.createShareableFile(residence: residence) {
|
||||
shareFileURL = url
|
||||
showShareSheet = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Data Loading
|
||||
|
||||
Reference in New Issue
Block a user