Add household sharing feature

 Features:
- Create household with 6-character shareable code
- Join existing household with code
- View household members and owner
- Leave household functionality
- Automatic inventory filtering by household
- Persistent household settings across app updates

🔧 Technical changes:
- Added Household model with Hive adapter (typeId: 4)
- Updated AppSettings with userName and currentHouseholdId fields
- Modified InventoryRepository to filter items by household
- Updated Add Item screen to set householdId on new items
- Added HouseholdScreen with full CRUD operations
- Integrated household sharing into Settings navigation

🎯 Behavior:
- Users not in a household see only their personal items
- Users in a household see shared household items
- New items automatically tagged with current household

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-04 14:46:10 -04:00
parent f4be460c3e
commit a360fadc17
9 changed files with 707 additions and 12 deletions

View File

@@ -19,11 +19,19 @@ class AppSettings extends HiveObject {
@HiveField(4)
String sortBy; // 'expiration', 'name', 'location'
@HiveField(5)
String? userName; // User's name for household sharing
@HiveField(6)
String? currentHouseholdId; // ID of the household they're in
AppSettings({
this.discordWebhookUrl,
this.expirationAlertsEnabled = true,
this.discordNotificationsEnabled = false,
this.defaultView = 'grid',
this.sortBy = 'expiration',
this.userName,
this.currentHouseholdId,
});
}

View File

@@ -22,13 +22,15 @@ class AppSettingsAdapter extends TypeAdapter<AppSettings> {
discordNotificationsEnabled: fields[2] as bool,
defaultView: fields[3] as String,
sortBy: fields[4] as String,
userName: fields[5] as String?,
currentHouseholdId: fields[6] as String?,
);
}
@override
void write(BinaryWriter writer, AppSettings obj) {
writer
..writeByte(5)
..writeByte(7)
..writeByte(0)
..write(obj.discordWebhookUrl)
..writeByte(1)
@@ -38,7 +40,11 @@ class AppSettingsAdapter extends TypeAdapter<AppSettings> {
..writeByte(3)
..write(obj.defaultView)
..writeByte(4)
..write(obj.sortBy);
..write(obj.sortBy)
..writeByte(5)
..write(obj.userName)
..writeByte(6)
..write(obj.currentHouseholdId);
}
@override

View File

@@ -0,0 +1,45 @@
import 'package:hive/hive.dart';
part 'household.g.dart';
@HiveType(typeId: 4)
class Household extends HiveObject {
@HiveField(0)
late String id; // Unique household code
@HiveField(1)
late String name;
@HiveField(2)
late String ownerName; // Person who created the household
@HiveField(3)
late DateTime createdAt;
@HiveField(4)
List<String> members; // List of member names
Household({
required this.id,
required this.name,
required this.ownerName,
DateTime? createdAt,
List<String>? members,
}) : createdAt = createdAt ?? DateTime.now(),
members = members ?? [];
/// Generate a random household code
static String generateCode() {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
final random = DateTime.now().millisecondsSinceEpoch;
var code = '';
var seed = random;
for (var i = 0; i < 6; i++) {
seed = (seed * 1103515245 + 12345) & 0x7fffffff;
code += chars[seed % chars.length];
}
return code;
}
}

View File

@@ -0,0 +1,53 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'household.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class HouseholdAdapter extends TypeAdapter<Household> {
@override
final int typeId = 4;
@override
Household read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return Household(
id: fields[0] as String,
name: fields[1] as String,
ownerName: fields[2] as String,
createdAt: fields[3] as DateTime?,
members: (fields[4] as List?)?.cast<String>(),
);
}
@override
void write(BinaryWriter writer, Household obj) {
writer
..writeByte(5)
..writeByte(0)
..write(obj.id)
..writeByte(1)
..write(obj.name)
..writeByte(2)
..write(obj.ownerName)
..writeByte(3)
..write(obj.createdAt)
..writeByte(4)
..write(obj.members);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is HouseholdAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}