Revert "hogar compartido: colaboracion entre cuentas sobre Firestore"

El hogar compartido cambia donde viven los datos, asi que se va a la 3.0 y la
2.x queda para correcciones. El trabajo sigue vivo en la rama 3.0.0 (163fd60).

Importante para esta rama: esto tambien retira el entitlement
com.apple.developer.applesignin, que sin la capability marcada en el App ID
habria roto la firma al subir la 2.1.1 a TestFlight.

This reverts commit 163fd60.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
This commit is contained in:
alexandrev-tibco
2026-09-12 13:08:27 +02:00
parent 163fd6026a
commit d8345a5b20
22 changed files with 8 additions and 2261 deletions
-2
View File
@@ -249,7 +249,6 @@ struct HomeView: View {
guard let settings = settings,
let plan = ensureCurrentWeekPlanExists(settings: settings) else { return }
viewModel.reconcileSlotsIfNeeded(plan: plan, settings: settings, context: context)
HouseholdSyncService.shared.focus(weekStart: viewModel.currentWeekStart)
}
}
@@ -795,7 +794,6 @@ struct HomeView: View {
language: settings.languageEnum.resolved()
)
wasWeekComplete = isWeekComplete(plan: plan)
HouseholdSyncService.shared.focus(weekStart: viewModel.currentWeekStart)
evaluatePostOnboardingPromptsIfNeeded(plan: plan, settings: settings)
evaluateWidgetPromo()
if settings.isPremium {
-309
View File
@@ -1,309 +0,0 @@
import SwiftUI
import SwiftData
import AuthenticationServices
/// Household screen: sign in, create or join a household, see who is in it and
/// leave. The content sync itself runs in `HouseholdSyncService`.
struct HouseholdView: View {
@Environment(\.modelContext) private var context
@Environment(\.dismiss) private var dismiss
@Query private var allSettings: [AppSettings]
@StateObject private var auth = AuthService.shared
@StateObject private var households = HouseholdService.shared
@StateObject private var sync = HouseholdSyncService.shared
@State private var householdName: String = ""
@State private var joinCode: String = ""
@State private var isWorking = false
@State private var errorMessage: String?
@State private var showJoinChoice = false
@State private var showLeaveConfirm = false
@State private var showPaywall = false
private var settings: AppSettings? { allSettings.first }
private var isPremium: Bool { settings?.isPremium ?? false }
private var isInHousehold: Bool { HouseholdRuntime.householdId != nil }
var body: some View {
Form {
if HouseholdRuntime.needsRelaunch {
Section {
Label("household_relaunch_needed", systemImage: "arrow.clockwise.circle.fill")
.font(.mealMoodSmall)
.foregroundColor(.mealMoodWarning)
}
.listRowBackground(Color.mealMoodSurface)
}
if !auth.isSignedIn {
signInSection
} else if isInHousehold {
householdSection
membersSection
inviteSection
leaveSection
} else {
createSection
joinSection
}
if let errorMessage {
Section {
Text(errorMessage)
.font(.mealMoodCaption)
.foregroundColor(.mealMoodWarning)
}
.listRowBackground(Color.mealMoodSurface)
}
}
.scrollContentBackground(.hidden)
.background(Color.mealMoodBackground.ignoresSafeArea())
.tint(.mealMoodCoral)
.navigationTitle("household_title")
.navigationBarTitleDisplayMode(.inline)
.disabled(isWorking)
.onAppear {
households.start()
AnalyticsService.logScreenView("Household")
}
.sheet(isPresented: $showPaywall) {
if let settings {
NavigationStack {
PremiumView(settings: settings, source: "household")
}
}
}
.confirmationDialog("household_join_choice_title", isPresented: $showJoinChoice, titleVisibility: .visible) {
Button("household_join_choice_merge") { join(bringingLocalContent: true) }
Button("household_join_choice_replace", role: .destructive) { join(bringingLocalContent: false) }
Button("reset_cancel", role: .cancel) {}
} message: {
Text("household_join_choice_message")
}
.alert("household_leave_confirm_title", isPresented: $showLeaveConfirm) {
Button("reset_cancel", role: .cancel) {}
Button("household_leave_confirm_confirm", role: .destructive) { leave() }
} message: {
Text("household_leave_confirm_message")
}
}
// MARK: - Sections
private var signInSection: some View {
Section {
Text("household_intro")
.font(.mealMoodCaption)
.foregroundColor(.mealMoodTextSecondary)
SignInWithAppleButton(.signIn) { request in
auth.prepare(request: request)
} onCompletion: { result in
Task {
do {
try await auth.completeSignInWithApple(result)
errorMessage = nil
} catch {
errorMessage = error.localizedDescription
}
}
}
.signInWithAppleButtonStyle(.black)
.frame(height: 46)
.listRowInsets(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
} footer: {
Text("household_sign_in_footer")
}
.listRowBackground(Color.mealMoodSurface)
}
private var createSection: some View {
Section {
TextField("household_name_placeholder", text: $householdName)
Button {
guard isPremium else {
showPaywall = true
AnalyticsService.logEvent("paywall_viewed", parameters: ["source": "household_create"])
return
}
create()
} label: {
HStack {
Label("household_create", systemImage: "house.fill")
if !isPremium {
Spacer()
Image(systemName: "star.circle.fill").foregroundColor(.mealMoodCoral)
}
}
}
.disabled(householdName.trimmingCharacters(in: .whitespaces).isEmpty)
} header: {
Text("household_create_section")
} footer: {
if isPremium {
Text("household_create_footer")
} else {
Text("household_create_premium_footer")
}
}
.listRowBackground(Color.mealMoodSurface)
}
private var joinSection: some View {
Section {
TextField("household_code_placeholder", text: $joinCode)
.textInputAutocapitalization(.characters)
.autocorrectionDisabled()
Button {
showJoinChoice = true
} label: {
Label("household_join", systemImage: "person.badge.plus")
}
.disabled(!HouseholdService.isPlausibleCode(joinCode))
} header: {
Text("household_join_section")
} footer: {
Text("household_join_footer")
}
.listRowBackground(Color.mealMoodSurface)
}
private var householdSection: some View {
Section {
HStack {
Label(households.household?.name ?? HouseholdRuntime.householdName ?? "", systemImage: "house.fill")
Spacer()
if sync.isSyncing {
ProgressView()
} else if let lastSyncedAt = sync.lastSyncedAt {
Text(lastSyncedAt.formatted(date: .omitted, time: .shortened))
.font(.mealMoodCaption)
.foregroundColor(.mealMoodTextSecondary)
}
}
if let syncError = sync.lastError {
Text(syncError)
.font(.mealMoodCaption)
.foregroundColor(.mealMoodWarning)
}
} header: {
Text("household_section")
}
.listRowBackground(Color.mealMoodSurface)
}
private var membersSection: some View {
Section {
ForEach(households.members) { member in
HStack {
Label(
member.displayName.isEmpty ? String(localized: "household_member_unnamed") : member.displayName,
systemImage: member.role == "owner" ? "crown.fill" : "person.fill"
)
Spacer()
if member.id == auth.uid {
Text("household_member_you")
.font(.mealMoodCaption)
.foregroundColor(.mealMoodTextSecondary)
}
}
}
} header: {
Text("household_members_section")
}
.listRowBackground(Color.mealMoodSurface)
}
private var inviteSection: some View {
Section {
if let code = households.household?.inviteCode {
HStack {
Text(code)
.font(.system(.title3, design: .monospaced))
.fontWeight(.bold)
.foregroundColor(.mealMoodTextPrimary)
Spacer()
ShareLink(item: String(format: String(localized: "household_invite_share"), code)) {
Image(systemName: "square.and.arrow.up")
}
}
if let expiry = households.household?.inviteExpiresAt {
Text(String(format: String(localized: "household_invite_expires"),
expiry.formatted(date: .abbreviated, time: .omitted)))
.font(.mealMoodCaption)
.foregroundColor(.mealMoodTextSecondary)
}
}
Button {
regenerateCode()
} label: {
Label("household_invite_regenerate", systemImage: "arrow.triangle.2.circlepath")
}
} header: {
Text("household_invite_section")
} footer: {
Text("household_invite_footer")
}
.listRowBackground(Color.mealMoodSurface)
}
private var leaveSection: some View {
Section {
Button(role: .destructive) {
showLeaveConfirm = true
} label: {
Label("household_leave", systemImage: "rectangle.portrait.and.arrow.right")
}
}
.listRowBackground(Color.mealMoodSurface)
}
// MARK: - Actions
private func create() {
run {
let name = householdName.trimmingCharacters(in: .whitespaces)
_ = try await households.createHousehold(name: name, displayName: auth.displayName ?? "")
// Everything already planned on this device becomes the household's
// starting point.
await sync.seedNewHousehold()
}
}
private func join(bringingLocalContent: Bool) {
run {
_ = try await households.join(code: joinCode, displayName: auth.displayName ?? "")
if !bringingLocalContent {
sync.replaceLocalContent(context: context)
}
joinCode = ""
}
}
private func leave() {
run {
try await households.leaveHousehold()
}
}
private func regenerateCode() {
run {
try await households.regenerateInviteCode()
}
}
private func run(_ operation: @escaping () async throws -> Void) {
isWorking = true
errorMessage = nil
Task {
do {
try await operation()
} catch {
errorMessage = error.localizedDescription
CrashlyticsService.record(error, context: "household_action")
}
isWorking = false
}
}
}
@@ -227,26 +227,6 @@ struct SettingsView: View {
.listRowBackground(Color.mealMoodSurface)
.task { await refreshNotificationStatus() }
// Household section (2.2): shared planning across accounts.
Section {
NavigationLink(destination: HouseholdView()) {
HStack {
Text("household_title")
Spacer()
if let name = HouseholdRuntime.householdName, HouseholdRuntime.householdId != nil {
Text(name)
.font(.mealMoodCaption)
.foregroundColor(.mealMoodTextSecondary)
}
}
}
} header: {
Label("household_section", systemImage: "person.2")
} footer: {
Text("household_settings_footer")
}
.listRowBackground(Color.mealMoodSurface)
// Tags section
Section {
NavigationLink(destination: TagListView()) {