almost finish status support everywhere else, group setting start impl
This commit is contained in:
parent
6b47888514
commit
92a95cb365
14 changed files with 770 additions and 116 deletions
3
drizzle/0001_tiresome_stature.sql
Normal file
3
drizzle/0001_tiresome_stature.sql
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
ALTER TABLE `group` ADD `change_title` integer DEFAULT 1 NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE `group` ADD `add_members` integer DEFAULT 1 NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE `group` ADD `remove_members` integer DEFAULT 0 NOT NULL;
|
||||||
556
drizzle/meta/0001_snapshot.json
Normal file
556
drizzle/meta/0001_snapshot.json
Normal file
|
|
@ -0,0 +1,556 @@
|
||||||
|
{
|
||||||
|
"version": "6",
|
||||||
|
"dialect": "sqlite",
|
||||||
|
"id": "e21369b9-d475-4c0f-8a6d-1c5f92ab8948",
|
||||||
|
"prevId": "bce65872-fa2f-4adc-b86f-af9880038bc8",
|
||||||
|
"tables": {
|
||||||
|
"channel": {
|
||||||
|
"name": "channel",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"server_id": {
|
||||||
|
"name": "server_id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"name": "messages",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'[]'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"channel_server_id_server_id_fk": {
|
||||||
|
"name": "channel_server_id_server_id_fk",
|
||||||
|
"tableFrom": "channel",
|
||||||
|
"tableTo": "server",
|
||||||
|
"columnsFrom": [
|
||||||
|
"server_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
},
|
||||||
|
"directMessage": {
|
||||||
|
"name": "directMessage",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"first_member": {
|
||||||
|
"name": "first_member",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"second_member": {
|
||||||
|
"name": "second_member",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"name": "messages",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'[]'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"directMessage_first_member_user_id_fk": {
|
||||||
|
"name": "directMessage_first_member_user_id_fk",
|
||||||
|
"tableFrom": "directMessage",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"first_member"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"directMessage_second_member_user_id_fk": {
|
||||||
|
"name": "directMessage_second_member_user_id_fk",
|
||||||
|
"tableFrom": "directMessage",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"second_member"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
},
|
||||||
|
"friendRequest": {
|
||||||
|
"name": "friendRequest",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"from_user": {
|
||||||
|
"name": "from_user",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"from_username": {
|
||||||
|
"name": "from_username",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"to_username": {
|
||||||
|
"name": "to_username",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"to_user": {
|
||||||
|
"name": "to_user",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"friendRequest_from_user_user_id_fk": {
|
||||||
|
"name": "friendRequest_from_user_user_id_fk",
|
||||||
|
"tableFrom": "friendRequest",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"from_user"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"friendRequest_from_username_user_id_fk": {
|
||||||
|
"name": "friendRequest_from_username_user_id_fk",
|
||||||
|
"tableFrom": "friendRequest",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"from_username"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"friendRequest_to_username_user_id_fk": {
|
||||||
|
"name": "friendRequest_to_username_user_id_fk",
|
||||||
|
"tableFrom": "friendRequest",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"to_username"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
},
|
||||||
|
"friendRequest_to_user_user_id_fk": {
|
||||||
|
"name": "friendRequest_to_user_user_id_fk",
|
||||||
|
"tableFrom": "friendRequest",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"to_user"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
},
|
||||||
|
"group": {
|
||||||
|
"name": "group",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"owner": {
|
||||||
|
"name": "owner",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"change_title": {
|
||||||
|
"name": "change_title",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": 1
|
||||||
|
},
|
||||||
|
"add_members": {
|
||||||
|
"name": "add_members",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": 1
|
||||||
|
},
|
||||||
|
"remove_members": {
|
||||||
|
"name": "remove_members",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"members": {
|
||||||
|
"name": "members",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'[]'"
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"name": "messages",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'[]'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"group_owner_user_id_fk": {
|
||||||
|
"name": "group_owner_user_id_fk",
|
||||||
|
"tableFrom": "group",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"owner"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
},
|
||||||
|
"invite": {
|
||||||
|
"name": "invite",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"server_id": {
|
||||||
|
"name": "server_id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"code": {
|
||||||
|
"name": "code",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"invite_server_id_server_id_fk": {
|
||||||
|
"name": "invite_server_id_server_id_fk",
|
||||||
|
"tableFrom": "invite",
|
||||||
|
"tableTo": "server",
|
||||||
|
"columnsFrom": [
|
||||||
|
"server_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
},
|
||||||
|
"server": {
|
||||||
|
"name": "server",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"owner": {
|
||||||
|
"name": "owner",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"members": {
|
||||||
|
"name": "members",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'[]'"
|
||||||
|
},
|
||||||
|
"channels": {
|
||||||
|
"name": "channels",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'[]'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"server_owner_user_id_fk": {
|
||||||
|
"name": "server_owner_user_id_fk",
|
||||||
|
"tableFrom": "server",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"owner"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
},
|
||||||
|
"session": {
|
||||||
|
"name": "session",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"user_id": {
|
||||||
|
"name": "user_id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"expires_at": {
|
||||||
|
"name": "expires_at",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {
|
||||||
|
"session_user_id_user_id_fk": {
|
||||||
|
"name": "session_user_id_user_id_fk",
|
||||||
|
"tableFrom": "session",
|
||||||
|
"tableTo": "user",
|
||||||
|
"columnsFrom": [
|
||||||
|
"user_id"
|
||||||
|
],
|
||||||
|
"columnsTo": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"onDelete": "no action",
|
||||||
|
"onUpdate": "no action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"name": "user",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": true,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"name": "username",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"password_hash": {
|
||||||
|
"name": "password_hash",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"status_overwrite": {
|
||||||
|
"name": "status_overwrite",
|
||||||
|
"type": "integer",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": 3
|
||||||
|
},
|
||||||
|
"friends": {
|
||||||
|
"name": "friends",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'[]'"
|
||||||
|
},
|
||||||
|
"servers": {
|
||||||
|
"name": "servers",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'[]'"
|
||||||
|
},
|
||||||
|
"groups": {
|
||||||
|
"name": "groups",
|
||||||
|
"type": "text",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "'[]'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"user_username_unique": {
|
||||||
|
"name": "user_username_unique",
|
||||||
|
"columns": [
|
||||||
|
"username"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
},
|
||||||
|
"user_email_unique": {
|
||||||
|
"name": "user_email_unique",
|
||||||
|
"columns": [
|
||||||
|
"email"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraints": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"views": {},
|
||||||
|
"enums": {},
|
||||||
|
"_meta": {
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {},
|
||||||
|
"columns": {}
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"indexes": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,13 @@
|
||||||
"when": 1767559403688,
|
"when": 1767559403688,
|
||||||
"tag": "0000_amusing_shatterstar",
|
"tag": "0000_amusing_shatterstar",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 1,
|
||||||
|
"version": "6",
|
||||||
|
"when": 1767860870240,
|
||||||
|
"tag": "0001_tiresome_stature",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -168,45 +168,10 @@
|
||||||
</Dialog.Header>
|
</Dialog.Header>
|
||||||
|
|
||||||
{#each data.friends as friend (friend.id)}
|
{#each data.friends as friend (friend.id)}
|
||||||
<Sidebar.MenuSubItem class="flex items-center gap-2">
|
<label class="flex items-center gap-2">
|
||||||
<Sidebar.MenuSubButton>
|
<input type="checkbox" name="member" value={friend.id} />
|
||||||
<User
|
<User crown={false} user={friend} />
|
||||||
onclick={(e) => {
|
</label>
|
||||||
e.preventDefault();
|
|
||||||
currentPage = friend.id;
|
|
||||||
}}
|
|
||||||
user={friend}
|
|
||||||
></User>
|
|
||||||
</Sidebar.MenuSubButton>
|
|
||||||
|
|
||||||
<Dialog.Root>
|
|
||||||
<Dialog.Trigger>
|
|
||||||
<Button variant="destructive" size="icon">
|
|
||||||
<MinusIcon />
|
|
||||||
</Button>
|
|
||||||
</Dialog.Trigger>
|
|
||||||
|
|
||||||
<Dialog.Content class="sm:max-w-106.25">
|
|
||||||
<Dialog.Header>
|
|
||||||
<Dialog.Title>Remove Friend</Dialog.Title>
|
|
||||||
<Dialog.Description>
|
|
||||||
Are you sure you want to remove {friend.username} from your friends?
|
|
||||||
</Dialog.Description>
|
|
||||||
</Dialog.Header>
|
|
||||||
|
|
||||||
<Dialog.Footer class="flex gap-2">
|
|
||||||
<Dialog.Close class={buttonVariants({ variant: 'outline' })}>
|
|
||||||
Cancel
|
|
||||||
</Dialog.Close>
|
|
||||||
|
|
||||||
<form method="POST" action="?/removeFriend">
|
|
||||||
<input type="hidden" name="userId" value={friend.id} />
|
|
||||||
<Button type="submit" variant="destructive">Remove</Button>
|
|
||||||
</form>
|
|
||||||
</Dialog.Footer>
|
|
||||||
</Dialog.Content>
|
|
||||||
</Dialog.Root>
|
|
||||||
</Sidebar.MenuSubItem>
|
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
<Dialog.Footer>
|
<Dialog.Footer>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,37 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Status, type UserWithStatus } from '$lib';
|
import { Status, type UserWithStatus } from '$lib';
|
||||||
|
import Crown from '@lucide/svelte/icons/crown';
|
||||||
|
|
||||||
const { onclick, user }: { onclick?: (e: MouseEvent) => void; user: UserWithStatus } = $props();
|
const {
|
||||||
|
onclick,
|
||||||
|
user,
|
||||||
|
crown
|
||||||
|
}: { crown: boolean; onclick?: (e: MouseEvent) => void; user: UserWithStatus } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<div class="flex flex-row gap-2">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
src={'https://api.dicebear.com/7.x/pixel-art/svg?seed=' + user.username}
|
||||||
|
alt={user.username}
|
||||||
|
class="size-6 rounded-full"
|
||||||
|
/>
|
||||||
|
<div class="relative">
|
||||||
|
{#if user.status === Status.OFFLINE}
|
||||||
|
<span
|
||||||
|
class="absolute end-0 bottom-0 block size-2 rounded-full bg-gray-500 ring-1 ring-white"
|
||||||
|
></span>
|
||||||
|
{:else if user.status === Status.DND}
|
||||||
|
<span class="absolute end-0 bottom-0 block size-2 rounded-full bg-red-500 ring-1 ring-white"
|
||||||
|
></span>
|
||||||
|
{:else if user.status === Status.ONLINE}
|
||||||
|
<span
|
||||||
|
class="absolute end-0 bottom-0 block size-2 rounded-full bg-green-500 ring-1 ring-white"
|
||||||
|
></span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
<a
|
<a
|
||||||
{onclick}
|
{onclick}
|
||||||
oncontextmenu={async (e) => {
|
oncontextmenu={async (e) => {
|
||||||
|
|
@ -13,22 +41,13 @@
|
||||||
href="##"
|
href="##"
|
||||||
class="flex items-center gap-2"
|
class="flex items-center gap-2"
|
||||||
>
|
>
|
||||||
<div class="relative">
|
|
||||||
<img
|
|
||||||
src={'https://api.dicebear.com/7.x/pixel-art/svg?seed=' + user.username}
|
|
||||||
alt={user.username}
|
|
||||||
class="size-6 rounded-full"
|
|
||||||
/>
|
|
||||||
{#if user.status === Status.OFFLINE}
|
|
||||||
<span class="absolute end-0 bottom-0 block size-2 rounded-full bg-gray-500 ring-1 ring-white"
|
|
||||||
></span>
|
|
||||||
{:else if user.status === Status.DND}
|
|
||||||
<span class="absolute end-0 bottom-0 block size-2 rounded-full bg-red-500 ring-1 ring-white"
|
|
||||||
></span>
|
|
||||||
{:else if user.status === Status.ONLINE}
|
|
||||||
<span class="absolute end-0 bottom-0 block size-2 rounded-full bg-green-500 ring-1 ring-white"
|
|
||||||
></span>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{user.username}
|
{user.username}
|
||||||
|
{#if crown}
|
||||||
|
<Crown></Crown>
|
||||||
|
{/if}
|
||||||
</a>
|
</a>
|
||||||
|
<div class="pl-2 text-xs text-gray-400 italic">
|
||||||
|
{user.statusMessage}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,128 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import UserRoundPlus from '@lucide/svelte/icons/user-round-plus';
|
import * as Dialog from '$lib/components/ui/dialog/index.js';
|
||||||
import UserRoundMinus from '@lucide/svelte/icons/user-round-minus';
|
import * as Tabs from '$lib/components/ui/tabs/index.js';
|
||||||
|
import Cog from '@lucide/svelte/icons/cog';
|
||||||
import * as Sidebar from '$lib/components/ui/sidebar/index.js';
|
import * as Sidebar from '$lib/components/ui/sidebar/index.js';
|
||||||
import { useSidebar } from '$lib/components/ui/sidebar/context.svelte.js';
|
import { useSidebar } from '$lib/components/ui/sidebar/context.svelte.js';
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import User from './extra/User.svelte';
|
import User from './extra/User.svelte';
|
||||||
import type { SessionValidationResult } from '$lib/server/auth';
|
import type { SessionValidationResult } from '$lib/server/auth';
|
||||||
import { ServerID, type UserWithStatus } from '$lib';
|
import {
|
||||||
|
GroupID,
|
||||||
|
ServerID,
|
||||||
|
type OverviewGroup,
|
||||||
|
type OverviewServer,
|
||||||
|
type UserWithStatus
|
||||||
|
} from '$lib';
|
||||||
|
import Button from './ui/button/button.svelte';
|
||||||
|
|
||||||
// Props for the member sidebar.
|
// Props for the member sidebar.
|
||||||
let {
|
let {
|
||||||
open = $bindable(true),
|
open = $bindable(true),
|
||||||
members = $bindable<UserWithStatus[]>([]),
|
members = $bindable<UserWithStatus[]>([]),
|
||||||
user,
|
user,
|
||||||
|
currentEntity,
|
||||||
currentEntityId = $bindable<string | null>(null)
|
currentEntityId = $bindable<string | null>(null)
|
||||||
}: {
|
}: {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
members: UserWithStatus[];
|
members: UserWithStatus[];
|
||||||
user: SessionValidationResult['user'];
|
user: SessionValidationResult['user'];
|
||||||
|
currentEntity: OverviewGroup | OverviewServer;
|
||||||
currentEntityId: string | null;
|
currentEntityId: string | null;
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
let sidebar_probably = useSidebar();
|
let this_sidebar = useSidebar();
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (sidebar_probably.open != open) {
|
if (this_sidebar.open != open) {
|
||||||
sidebar_probably.setOpen(open);
|
this_sidebar.setOpen(open);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Sidebar.Root side="right">
|
<Sidebar.Root side="right">
|
||||||
|
<Sidebar.Header>
|
||||||
|
<div class="align-center flex w-full justify-center">
|
||||||
|
{#if user && currentEntityId}
|
||||||
|
<Dialog.Root>
|
||||||
|
<Dialog.Trigger><Button variant="outline"><Cog></Cog></Button></Dialog.Trigger>
|
||||||
|
<Dialog.Content class="sm:max-w-[425px]">
|
||||||
|
<Dialog.Header>
|
||||||
|
<Dialog.Title>Group Settings</Dialog.Title>
|
||||||
|
<Dialog.Description>Configure your group settings here.</Dialog.Description>
|
||||||
|
</Dialog.Header>
|
||||||
|
|
||||||
|
<Tabs.Root value="users" class="w-[400px]">
|
||||||
|
<Tabs.List class="grid w-full grid-cols-2">
|
||||||
|
<Tabs.Trigger value="users">User Permissions</Tabs.Trigger>
|
||||||
|
{#if user.id == currentEntity.ownerId}
|
||||||
|
<Tabs.Trigger value="admins">Admin Settings</Tabs.Trigger>
|
||||||
|
{/if}
|
||||||
|
</Tabs.List>
|
||||||
|
{#if ServerID.is(currentEntityId)}
|
||||||
|
<h1>not done yet for later</h1>
|
||||||
|
{:else if GroupID.is(currentEntityId)}
|
||||||
|
{#if user.id == currentEntity.ownerId}
|
||||||
|
<Tabs.Content value="admins">
|
||||||
|
<form method="POST" action="?/configureGroup" class="space-y-4 p-2">
|
||||||
|
<input type="hidden" name="groupId" value={currentEntityId} />
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<label for="addUsers">Allow everyone to add users</label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="addMembers"
|
||||||
|
name="addMembers"
|
||||||
|
checked={(currentEntity as OverviewGroup).permissions.addMembers}
|
||||||
|
class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<label for="removeUsers">Allow everyone to remove users</label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="removeUsers"
|
||||||
|
name="removeUsers"
|
||||||
|
checked={(currentEntity as OverviewGroup).permissions.removeMembers}
|
||||||
|
class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<label for="changeTitle">Allow everyone to change title</label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="changeTitle"
|
||||||
|
name="changeTitle"
|
||||||
|
checked={(currentEntity as OverviewGroup).permissions.changeTitle}
|
||||||
|
class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button type="submit" class="w-full">Save Changes</Button>
|
||||||
|
</form>
|
||||||
|
</Tabs.Content>
|
||||||
|
{/if}
|
||||||
|
<Tabs.Content value="users">
|
||||||
|
<div class="space-y-4 p-2">
|
||||||
|
{#if (currentEntity as OverviewGroup).permissions.addMembers || user.id == currentEntity.ownerId}
|
||||||
|
<h1>you have permission to add members</h1>
|
||||||
|
{/if}
|
||||||
|
{#if (currentEntity as OverviewGroup).permissions.changeTitle || user.id == currentEntity.ownerId}
|
||||||
|
<h1>you have permission to change title</h1>
|
||||||
|
{/if}
|
||||||
|
{#if (currentEntity as OverviewGroup).permissions.removeMembers || user.id == currentEntity.ownerId}
|
||||||
|
<h1>you have permission to remove members</h1>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</Tabs.Content>
|
||||||
|
{/if}
|
||||||
|
</Tabs.Root>
|
||||||
|
</Dialog.Content>
|
||||||
|
</Dialog.Root>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</Sidebar.Header>
|
||||||
<Sidebar.Content>
|
<Sidebar.Content>
|
||||||
<Sidebar.Group>
|
<Sidebar.Group>
|
||||||
<Sidebar.GroupLabel>Members</Sidebar.GroupLabel>
|
<Sidebar.GroupLabel>Members</Sidebar.GroupLabel>
|
||||||
|
|
@ -41,7 +133,7 @@
|
||||||
<Sidebar.MenuItem>
|
<Sidebar.MenuItem>
|
||||||
<Sidebar.MenuButton>
|
<Sidebar.MenuButton>
|
||||||
{#snippet child({ props })}
|
{#snippet child({ props })}
|
||||||
<User user={member} />
|
<User user={member} crown={member.id == currentEntity.ownerId} />
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</Sidebar.MenuButton>
|
</Sidebar.MenuButton>
|
||||||
</Sidebar.MenuItem>
|
</Sidebar.MenuItem>
|
||||||
|
|
@ -49,45 +141,5 @@
|
||||||
</Sidebar.Menu>
|
</Sidebar.Menu>
|
||||||
</Sidebar.GroupContent>
|
</Sidebar.GroupContent>
|
||||||
</Sidebar.Group>
|
</Sidebar.Group>
|
||||||
|
|
||||||
{#if currentEntityId && ServerID.is(currentEntityId) && user}
|
|
||||||
<Sidebar.Group>
|
|
||||||
<Sidebar.GroupLabel>Server Actions</Sidebar.GroupLabel>
|
|
||||||
|
|
||||||
<Sidebar.GroupContent>
|
|
||||||
<Sidebar.Menu>
|
|
||||||
<Sidebar.MenuItem>
|
|
||||||
<Sidebar.MenuButton>
|
|
||||||
{#snippet child({ props })}
|
|
||||||
<form method="POST" action="?/inviteUser" class="w-full">
|
|
||||||
<input type="hidden" name="serverId" value={currentEntityId} />
|
|
||||||
<button type="submit" class="flex w-full items-center gap-2" {...props}>
|
|
||||||
<UserRoundPlus class="size-4" />
|
|
||||||
<span>Invite User</span>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
{/snippet}
|
|
||||||
</Sidebar.MenuButton>
|
|
||||||
</Sidebar.MenuItem>
|
|
||||||
|
|
||||||
{#if user.id === members.find((m) => m.id === currentEntityId)?.ownerId}
|
|
||||||
<Sidebar.MenuItem>
|
|
||||||
<Sidebar.MenuButton>
|
|
||||||
{#snippet child({ props })}
|
|
||||||
<form method="POST" action="?/leaveServer" class="w-full">
|
|
||||||
<input type="hidden" name="serverId" value={currentEntityId} />
|
|
||||||
<button type="submit" class="flex w-full items-center gap-2" {...props}>
|
|
||||||
<UserRoundMinus class="size-4" />
|
|
||||||
<span>Leave Server</span>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
{/snippet}
|
|
||||||
</Sidebar.MenuButton>
|
|
||||||
</Sidebar.MenuItem>
|
|
||||||
{/if}
|
|
||||||
</Sidebar.Menu>
|
|
||||||
</Sidebar.GroupContent>
|
|
||||||
</Sidebar.Group>
|
|
||||||
{/if}
|
|
||||||
</Sidebar.Content>
|
</Sidebar.Content>
|
||||||
</Sidebar.Root>
|
</Sidebar.Root>
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,11 @@ export type OverviewGroup = {
|
||||||
ownerId: string;
|
ownerId: string;
|
||||||
members: number;
|
members: number;
|
||||||
image: string;
|
image: string;
|
||||||
|
permissions: {
|
||||||
|
changeTitle: boolean;
|
||||||
|
addMembers: boolean;
|
||||||
|
removeMembers: boolean;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface UserWithStatus extends OverviewUser {
|
export interface UserWithStatus extends OverviewUser {
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,10 @@ export async function validateSessionToken(token: string) {
|
||||||
id: table.group.id,
|
id: table.group.id,
|
||||||
name: table.group.name,
|
name: table.group.name,
|
||||||
ownerId: table.group.owner,
|
ownerId: table.group.owner,
|
||||||
members: table.group.members
|
members: table.group.members,
|
||||||
|
changeTitle: table.group.changeTitle,
|
||||||
|
addMembers: table.group.addMembers,
|
||||||
|
removeMembers: table.group.removeMembers
|
||||||
})
|
})
|
||||||
.from(table.group)
|
.from(table.group)
|
||||||
.where(inArray(table.group.id, user.groups as string[]))
|
.where(inArray(table.group.id, user.groups as string[]))
|
||||||
|
|
@ -124,7 +127,15 @@ export async function validateSessionToken(token: string) {
|
||||||
servers,
|
servers,
|
||||||
friends,
|
friends,
|
||||||
groups: groups.map((z) => {
|
groups: groups.map((z) => {
|
||||||
return { ...z, members: (z.members as string[]).length };
|
return {
|
||||||
|
...z,
|
||||||
|
members: (z.members as string[]).length,
|
||||||
|
permissions: {
|
||||||
|
changeTitle: !!z.changeTitle,
|
||||||
|
addMembers: !!z.addMembers,
|
||||||
|
removeMembers: !!z.removeMembers
|
||||||
|
}
|
||||||
|
};
|
||||||
}),
|
}),
|
||||||
friendRequests
|
friendRequests
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { boolean } from 'drizzle-orm/singlestore-core';
|
||||||
import { Status } from '../../index.ts';
|
import { Status } from '../../index.ts';
|
||||||
import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
|
import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
|
||||||
|
|
||||||
|
|
@ -37,6 +38,9 @@ export const group = sqliteTable('group', {
|
||||||
owner: text('owner')
|
owner: text('owner')
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => user.id),
|
.references(() => user.id),
|
||||||
|
changeTitle: integer('change_title').default(1).notNull(),
|
||||||
|
addMembers: integer('add_members').default(1).notNull(),
|
||||||
|
removeMembers: integer('remove_members').default(0).notNull(),
|
||||||
members: text('members', { mode: 'json' }).default([]).notNull(),
|
members: text('members', { mode: 'json' }).default([]).notNull(),
|
||||||
messages: text('messages', { mode: 'json' }).default([]).notNull()
|
messages: text('messages', { mode: 'json' }).default([]).notNull()
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { db } from '$lib/server/db';
|
import { db, kvStore } from '$lib/server/db';
|
||||||
import * as table from '$lib/server/db/schema';
|
import * as table from '$lib/server/db/schema';
|
||||||
import { eq, inArray } from 'drizzle-orm';
|
import { eq, inArray } from 'drizzle-orm';
|
||||||
import { GroupID, ServerID } from '$lib';
|
import { GroupID, ServerID } from '$lib';
|
||||||
|
|
@ -27,6 +27,9 @@ export const GET: RequestHandler = async ({ params }) => {
|
||||||
return json({
|
return json({
|
||||||
members: members.map((member) => ({
|
members: members.map((member) => ({
|
||||||
id: member.id,
|
id: member.id,
|
||||||
|
status: kvStore.get('user-' + member.id + '-state'),
|
||||||
|
//@TODO Implement statusmessage
|
||||||
|
statusMessage: Math.random() > 0.5 ? 'vibing 🟢' : 'not vibing',
|
||||||
username: member.username,
|
username: member.username,
|
||||||
image: `https://api.dicebear.com/7.x/pixel-art/svg?seed=${member.username}`
|
image: `https://api.dicebear.com/7.x/pixel-art/svg?seed=${member.username}`
|
||||||
}))
|
}))
|
||||||
|
|
@ -48,6 +51,9 @@ export const GET: RequestHandler = async ({ params }) => {
|
||||||
return json({
|
return json({
|
||||||
members: members.map((member) => ({
|
members: members.map((member) => ({
|
||||||
id: member.id,
|
id: member.id,
|
||||||
|
status: kvStore.get('user-' + member.id + '-state'),
|
||||||
|
//@TODO Implement statusmessage
|
||||||
|
statusMessage: Math.random() > 0.5 ? 'vibing 🟢' : 'not vibing',
|
||||||
username: member.username,
|
username: member.username,
|
||||||
image: `https://api.dicebear.com/7.x/pixel-art/svg?seed=${member.username}`
|
image: `https://api.dicebear.com/7.x/pixel-art/svg?seed=${member.username}`
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { json } from '@sveltejs/kit';
|
import { json } from '@sveltejs/kit';
|
||||||
import type { RequestHandler } from './$types';
|
import type { RequestHandler } from './$types';
|
||||||
import { kvStore } from '$lib/server/db';
|
import { kvStore } from '$lib/server/db';
|
||||||
|
import { Status } from '$lib';
|
||||||
|
|
||||||
export const GET: RequestHandler = async ({ params }) => {
|
export const GET: RequestHandler = async ({ params }) => {
|
||||||
const { userId } = params;
|
const { userId } = params;
|
||||||
|
|
@ -9,6 +10,11 @@ export const GET: RequestHandler = async ({ params }) => {
|
||||||
userId,
|
userId,
|
||||||
status: kvStore.get('user-' + userId + '-state'),
|
status: kvStore.get('user-' + userId + '-state'),
|
||||||
//@TODO Implement statusmessage
|
//@TODO Implement statusmessage
|
||||||
statusMessage: Math.random() > 0.5 ? 'vibing 🟢' : null
|
statusMessage:
|
||||||
|
kvStore.get('user-' + userId + '-state') != Status.OFFLINE
|
||||||
|
? Math.random() > 0.5
|
||||||
|
? 'vibing 🟢'
|
||||||
|
: 'not vibing'
|
||||||
|
: ''
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ export async function GET({ locals, request }) {
|
||||||
const userId = locals.user.id;
|
const userId = locals.user.id;
|
||||||
//@TODO add more to subscribed eventually, server members, et cetera
|
//@TODO add more to subscribed eventually, server members, et cetera
|
||||||
const subscribed = locals.user.friends.map((f) => f.id);
|
const subscribed = locals.user.friends.map((f) => f.id);
|
||||||
|
subscribed.push(userId); // shit such as friend requests
|
||||||
|
|
||||||
const overwrite = locals.user.statusOverwrite;
|
const overwrite = locals.user.statusOverwrite;
|
||||||
|
|
||||||
const sessionId = crypto.randomUUID();
|
const sessionId = crypto.randomUUID();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { DirectMessageID, FriendRequestID, GroupID, ServerID } from '$lib';
|
||||||
import { eq } from 'drizzle-orm';
|
import { eq } from 'drizzle-orm';
|
||||||
import { and } from 'drizzle-orm';
|
import { and } from 'drizzle-orm';
|
||||||
import { type User } from '$lib/server/db/schema';
|
import { type User } from '$lib/server/db/schema';
|
||||||
|
import { _sendToSubscribers } from '../api/updates/+server';
|
||||||
export const load: PageServerLoad = async () => {
|
export const load: PageServerLoad = async () => {
|
||||||
const user = requireLogin();
|
const user = requireLogin();
|
||||||
return { user };
|
return { user };
|
||||||
|
|
@ -92,6 +93,8 @@ export const actions = {
|
||||||
.where(eq(table.user.id, user[0].id));
|
.where(eq(table.user.id, user[0].id));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_sendToSubscribers(locals.user!.id, { type: 'friends', status: 'accepted' });
|
||||||
|
_sendToSubscribers(user[0].id, { type: 'friends', status: 'accepted' });
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,6 +114,8 @@ export const actions = {
|
||||||
fromUsername: locals.user!.username
|
fromUsername: locals.user!.username
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_sendToSubscribers(locals.user!.id, { type: 'friends', status: 'sent-request' });
|
||||||
|
_sendToSubscribers(user[0].id, { type: 'friends', status: 'new-request' });
|
||||||
return { success: true };
|
return { success: true };
|
||||||
},
|
},
|
||||||
removeFriend: async ({ request, locals }) => {
|
removeFriend: async ({ request, locals }) => {
|
||||||
|
|
@ -185,6 +190,9 @@ export const actions = {
|
||||||
// delete the request
|
// delete the request
|
||||||
await db.delete(table.friendRequest).where(eq(table.friendRequest.id, requestId)).limit(1);
|
await db.delete(table.friendRequest).where(eq(table.friendRequest.id, requestId)).limit(1);
|
||||||
|
|
||||||
|
_sendToSubscribers(fr.fromUser, { type: 'friends', status: 'request-cancelled' });
|
||||||
|
_sendToSubscribers(fr.toUser, { type: 'friends', status: 'request-cancelled' });
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
},
|
},
|
||||||
createGroup: async ({ request, locals }) => {
|
createGroup: async ({ request, locals }) => {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
let { form, data }: { form: ActionData; data: PageServerData } = $props();
|
let { form, data }: { form: ActionData; data: PageServerData } = $props();
|
||||||
let currentPageID: (UserId | GroupId | ServerId) | null = $state(null);
|
let currentPageID: (UserId | GroupId | ServerId) | null = $state(null);
|
||||||
let currentPage: OverviewUser | OverviewGroup | OverviewServer | undefined = $state();
|
let currentPage: OverviewUser | OverviewGroup | OverviewServer | undefined = $state();
|
||||||
|
let ownerId: string | null = $state(null);
|
||||||
let isMembersTabOpen = $state(true);
|
let isMembersTabOpen = $state(true);
|
||||||
let members: UserWithStatus[] = $state([]);
|
let members: UserWithStatus[] = $state([]);
|
||||||
|
|
||||||
|
|
@ -72,6 +72,7 @@
|
||||||
members = data.members;
|
members = data.members;
|
||||||
}
|
}
|
||||||
fetchMembers();
|
fetchMembers();
|
||||||
|
ownerId = (currentPage as OverviewGroup | OverviewServer).ownerId;
|
||||||
} else {
|
} else {
|
||||||
isMembersTabOpen = false;
|
isMembersTabOpen = false;
|
||||||
}
|
}
|
||||||
|
|
@ -125,6 +126,7 @@
|
||||||
name: z.name,
|
name: z.name,
|
||||||
ownerId: z.ownerId,
|
ownerId: z.ownerId,
|
||||||
members: z.members,
|
members: z.members,
|
||||||
|
permissions: z.permissions,
|
||||||
image: 'https://api.dicebear.com/7.x/pixel-art/svg?seed=' + z.name
|
image: 'https://api.dicebear.com/7.x/pixel-art/svg?seed=' + z.name
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
@ -160,15 +162,22 @@
|
||||||
const json = JSON.parse(e.data) as
|
const json = JSON.parse(e.data) as
|
||||||
| { type: 'connected'; sessionId: string }
|
| { type: 'connected'; sessionId: string }
|
||||||
| { type: 'message'; message: ReturnMessage }
|
| { type: 'message'; message: ReturnMessage }
|
||||||
| { type: 'status'; id: string; status: 1 | 2 | 3 };
|
| { type: 'status'; id: string; status: 1 | 2 | 3 }
|
||||||
|
| { type: 'friends'; status: string };
|
||||||
|
|
||||||
|
if (json.type == 'friends') {
|
||||||
|
alert(json.status);
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
if (json.type == 'connected') {
|
if (json.type == 'connected') {
|
||||||
console.log('SSE connected. We are sessionID ' + json.sessionId);
|
console.log('SSE connected. We are sessionID ' + json.sessionId);
|
||||||
sessionId = json.sessionId;
|
sessionId = json.sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.type == 'status') {
|
if (json.type == 'status') {
|
||||||
|
//@TODO update everywhere where user is used
|
||||||
const friend = overview_data.friends.find((z) => z.id == json.id);
|
const friend = overview_data.friends.find((z) => z.id == json.id);
|
||||||
|
|
||||||
if (friend) {
|
if (friend) {
|
||||||
friend.status = json.status;
|
friend.status = json.status;
|
||||||
}
|
}
|
||||||
|
|
@ -325,6 +334,7 @@
|
||||||
bind:open={isMembersTabOpen}
|
bind:open={isMembersTabOpen}
|
||||||
user={data.user}
|
user={data.user}
|
||||||
{members}
|
{members}
|
||||||
|
currentEntity={currentPage}
|
||||||
currentEntityId={currentPageID}
|
currentEntityId={currentPageID}
|
||||||
/>
|
/>
|
||||||
</Sidebar.Provider>
|
</Sidebar.Provider>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue