actions-test/lib/backend/room.dart
Jakob Meier 7b23b12125
Implemented room member and room info
In preperation for upcoming room screens.

RoomInfo is supposed to be used in conjunction with
the Room class.
They are not merged (Room as a attribut in RoomInfo),
because whilst Room can be stored on disk,
RoomInfo can not.
This is done to prevent tampering with the data
(when offline).

This also makes hiding elements easier when the user is offline,
as we can just pretend, that they do not have the required permission.
2023-03-22 21:12:04 +01:00

310 lines
6.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:localstore/localstore.dart';
class RoomVisibility {
final int type;
const RoomVisibility(this.type);
static RoomVisibility get private {
return const RoomVisibility(0);
}
static RoomVisibility get local {
return const RoomVisibility(1);
}
static RoomVisibility get public {
return const RoomVisibility(2);
}
IconData get icon {
if (type == 2) {
return Icons.public;
} else if (type == 1) {
return Icons.home;
}
return Icons.lock;
}
String get text {
if (type == 2) {
return "Global";
} else if (type == 1) {
return "Local";
}
return "Private";
}
static List<RoomVisibility> list() {
return [
RoomVisibility.private,
RoomVisibility.local,
RoomVisibility.public,
];
}
}
class RoomIcon {
final String type;
RoomIcon({required this.type});
static RoomIcon get love {
return RoomIcon(type: "Love");
}
static RoomIcon get sports {
return RoomIcon(type: "Sports");
}
static RoomIcon get pets {
return RoomIcon(type: "Pets");
}
static RoomIcon get vacation {
return RoomIcon(type: "Vacation");
}
static RoomIcon get gifts {
return RoomIcon(type: "Gifts");
}
static RoomIcon get groceries {
return RoomIcon(type: "Groceries");
}
static RoomIcon get fashion {
return RoomIcon(type: "Fashion");
}
static RoomIcon get art {
return RoomIcon(type: "Art");
}
static RoomIcon get tech {
return RoomIcon(type: "Tech");
}
static RoomIcon get home {
return RoomIcon(type: "Home");
}
static RoomIcon get family {
return RoomIcon(type: "Family");
}
static RoomIcon get social {
return RoomIcon(type: "Social");
}
static RoomIcon get other {
return RoomIcon(type: "Other");
}
static List<RoomIcon> list() {
return [
RoomIcon.love,
RoomIcon.sports,
RoomIcon.pets,
RoomIcon.vacation,
RoomIcon.gifts,
RoomIcon.groceries,
RoomIcon.fashion,
RoomIcon.art,
RoomIcon.tech,
RoomIcon.home,
RoomIcon.family,
RoomIcon.social,
RoomIcon.other,
];
}
String get text {
switch (type.toLowerCase()) {
case 'love':
return 'Friends';
case 'sports':
return 'Sports';
case 'pets':
return 'Pets';
case 'vacation':
return 'Vacation';
case 'gifts':
return 'Gifts';
case 'groceries':
return 'Groceries';
case 'fashion':
return 'Clothing';
case 'art':
return 'Arts & Crafts';
case 'tech':
return 'Electronics';
case 'home':
return 'Home supplies';
case 'family':
return 'Family';
case 'social':
return 'Social';
case 'other':
default:
return 'Other';
}
}
// return image name
String get img {
switch (type.toLowerCase()) {
case 'love':
return 'undraw/undraw_couple.svg';
case 'sports':
return 'undraw/undraw_greek_freak.svg';
case 'pets':
return 'undraw/undraw_dog.svg';
case 'vacation':
return 'undraw/undraw_trip.svg';
case 'gifts':
return 'undraw/undraw_gifts.svg';
case 'groceries':
return 'undraw/undraw_gone_shopping.svg';
case 'fashion':
return 'undraw/undraw_jewelry.svg';
case 'art':
return 'undraw/undraw_sculpting.svg';
case 'tech':
return 'undraw/undraw_progressive_app.svg';
case 'home':
return 'undraw/undraw_under_construction.svg';
case 'family':
return 'undraw/undraw_family.svg';
case 'social':
return 'undraw/undraw_pizza_sharing.svg';
case 'other':
default:
return 'undraw/undraw_file_manager.svg';
}
}
}
class Room {
final String id;
final String serverTag;
final String name;
final String description;
RoomIcon? icon = RoomIcon.other;
RoomVisibility? visibility = RoomVisibility.private;
Room(
{required this.id,
required this.serverTag,
this.name = "",
this.description = "",
this.icon,
this.visibility});
// get list of all known rooms
static Future<List<Room>> listRooms() async {
final db = Localstore.instance;
final rooms = (await db.collection('rooms').get())!;
List<Room> builder = [];
for (MapEntry entry in rooms.entries) {
try {
builder.add(Room.fromMap(entry.value));
} catch (e) {
// skip invalid rooms
// NOTE: might want to autodelete them in the future
// although keeping them might be ok,
// in case we ever get a new dataset to fix the current state
}
}
return builder;
}
// listen to room change
static listen(Function(Map<String, dynamic>) cb) async {
final db = Localstore.instance;
final stream = db.collection('rooms').stream;
stream.listen(cb);
}
factory Room.fromMap(Map<String, dynamic> map) {
return Room(
id: map['id'],
serverTag: map['server'],
name: map['name'],
description: map['description'] ?? '',
icon: RoomIcon(type: map['icon'] ?? 'Other'),
visibility: RoomVisibility(map['visibility'] ?? 0));
}
Map<String, dynamic> toMap() {
return {
'id': id,
'server': serverTag,
'description': description,
'name': name,
'icon': icon?.type,
'visibility': visibility?.type
};
}
factory Room.fromJSON(dynamic json) {
return Room(
id: json['name'],
serverTag: json['server'],
name: json['title'],
description: json['description'],
icon: RoomIcon(type: json['icon']),
visibility: RoomVisibility(json['visibility']));
}
Future<void> toDisk() async {
final db = Localstore.instance;
await db.collection('rooms').doc('$id@$serverTag').set(toMap());
}
static Future<Room> fromDisk({required String id, required String serverTag}) async {
final db = Localstore.instance;
final raw = await db.collection('rooms').doc('$id@$serverTag').get();
return Room.fromMap(raw!);
}
}
class ShoppingListItem {
}
class RoomMember {
final String id;
final String serverTag;
final bool isAdmin;
const RoomMember(
{required this.id, required this.serverTag, required this.isAdmin});
factory RoomMember.fromJSON(dynamic json) {
return RoomMember(
id: json['name'], serverTag: json['server'], isAdmin: json['admin']);
}
}
class RoomInfo {
final String owner;
final bool isAdmin;
final bool isOwner;
final int permissions;
const RoomInfo(
{required this.permissions,
required this.owner,
required this.isAdmin,
required this.isOwner});
factory RoomInfo.fromJSON(dynamic json) {
return RoomInfo(
permissions: json['rights'],
owner: json['owner'],
isAdmin: json['isAdmin'],
isOwner: json['isOwner']);
}
}