Allow user to set a username; Show list of users on estimation screen

This commit is contained in:
Pijus Kamandulis
2024-10-12 17:20:16 +03:00
parent f4d3005acd
commit 40b1ef6f0c
18 changed files with 423 additions and 45 deletions

View File

@@ -1,4 +1,4 @@
import { Client, Databases } from 'node-appwrite';
import { Client, Databases, Models, Users } from 'node-appwrite';
import { AppwriteRuntimeContext, AppwriteSendReturn } from './definitions.mjs';
const joinSession = async ({
@@ -13,6 +13,7 @@ const joinSession = async ({
ctx: AppwriteRuntimeContext;
}): Promise<AppwriteSendReturn> => {
const databases = new Databases(client);
const users = new Users(client);
let estimation;
try {
@@ -31,16 +32,43 @@ const joinSession = async ({
);
}
let user: Models.User<Models.Preferences>;
try {
user = await users.get(userId);
} catch (e) {
error({ e });
return res.json(
{
message: 'Failed to get user',
},
500,
);
}
try {
const permissions: string[] = estimation['$permissions'];
permissions.push(`read("user:${userId}")`);
permissions.push(`update("user:${userId}")`);
const playerIds: string[] = estimation['playerIds'];
playerIds.push(userId);
const players: string[] = estimation['players'];
players.push(
JSON.stringify({
userId,
name: user.name.length > 0 ? user.name : `Guest - ${userId}`,
}),
);
await databases.updateDocument(
Bun.env.APPWRITE_DATABASE_ID,
Bun.env.APPWRITE_ESTIMATION_SESSION_COLLECTION_ID,
estimationId,
{},
{
playerIds,
players,
},
permissions,
);

View File

@@ -0,0 +1,2 @@
# Directory used by Appwrite CLI for local development
.appwrite

View File

@@ -0,0 +1,10 @@
# Username Change Handler
This function is called when a user changes his username.
Currently this funcion updates users name accross all of his estimation sessions.
## Environment Variables
- APPWRITE_DATABASE_ID - Database Id
- APPWRITE_ESTIMATION_SESSION_COLLECTION_ID - Sessions collection Id

View File

@@ -0,0 +1,7 @@
module openruntimes/handler
go 1.23.0
require github.com/open-runtimes/types-for-go/v4 v4.0.6
require github.com/appwrite/sdk-for-go v0.0.1-rc.2

View File

@@ -0,0 +1,4 @@
github.com/appwrite/sdk-for-go v0.0.1-rc.2 h1:kh8p6OmSgA4d7aT1KXE9Z3W99ioDKdhhY1OrKsTLu1I=
github.com/appwrite/sdk-for-go v0.0.1-rc.2/go.mod h1:aFiOAbfOzGS3811eMCt3T9WDBvjvPVAfOjw10Vghi4E=
github.com/open-runtimes/types-for-go/v4 v4.0.6 h1:0Xf58LMy/vwWkiRN6BvvpWt1mWzcWUWQ5wsWSezG2TU=
github.com/open-runtimes/types-for-go/v4 v4.0.6/go.mod h1:ab4mDSfgeG4kN8wWpaBSv0Ao3m9P6oEfN5gsXtx+iaI=

View File

@@ -0,0 +1,134 @@
package handler
import (
"encoding/json"
"os"
"github.com/appwrite/sdk-for-go/appwrite"
"github.com/appwrite/sdk-for-go/models"
"github.com/appwrite/sdk-for-go/query"
"github.com/open-runtimes/types-for-go/v4/openruntimes"
)
type Response struct {
Message string `json:"message"`
}
type ErrorResponse struct {
Error string `json:"error"`
}
type EstimationSession struct {
Id string `json:"$id"`
UserID string `json:"userId"`
Name string `json:"name"`
Tickets []string `json:"tickets"`
SessionState string `json:"sessionState"`
Players []string `json:"players"`
PlayerIDs []string `json:"playerIds"`
}
type EstimationSessionList struct {
Total int `json:"total"`
Documents []EstimationSession `json:"documents"`
}
type Player struct {
UserID string `json:"userId"`
Name string `json:"name"`
}
func Main(Context openruntimes.Context) openruntimes.Response {
databaseId := os.Getenv("APPWRITE_DATABASE_ID")
collectionId := os.Getenv("APPWRITE_ESTIMATION_SESSION_COLLECTION_ID")
if databaseId == "" || collectionId == "" {
Context.Error("Environment variables not provided")
return Context.Res.Json(ErrorResponse{
Error: "Environment variables not provided",
}, Context.Res.WithStatusCode(500))
}
var userData models.User
Context.Req.BodyJson(&userData)
if userData.Id == "" {
Context.Log("Request body did not contain id")
return Context.Res.Json(ErrorResponse{
Error: "User id was not provided",
}, Context.Res.WithStatusCode(400))
}
client := appwrite.NewClient(
appwrite.WithEndpoint(os.Getenv("APPWRITE_FUNCTION_API_ENDPOINT")),
appwrite.WithProject(os.Getenv("APPWRITE_FUNCTION_PROJECT_ID")),
appwrite.WithKey(Context.Req.Headers["x-appwrite-key"]),
)
databases := appwrite.NewDatabases(client)
queries := []string{query.Contains("playerIds", userData.Id)}
userEstimationSessions, err := databases.ListDocuments(databaseId, collectionId, databases.WithListDocumentsQueries(queries))
if err != nil {
Context.Error(err.Error())
return Context.Res.Json(ErrorResponse{
Error: err.Error(),
}, Context.Res.WithStatusCode(500))
}
var documents EstimationSessionList
err = userEstimationSessions.Decode(&documents)
if err != nil {
Context.Error(err.Error())
return Context.Res.Json(ErrorResponse{
Error: err.Error(),
}, Context.Res.WithStatusCode(500))
}
newUsername := userData.Name
if newUsername == "" {
newUsername = "Guest - " + userData.Id
}
for _, estimationSession := range documents.Documents {
for i, jsonString := range estimationSession.Players {
var player Player
err := json.Unmarshal([]byte(jsonString), &player)
if err != nil {
Context.Error(err.Error())
return Context.Res.Json(ErrorResponse{
Error: err.Error(),
}, Context.Res.WithStatusCode(500))
}
if player.UserID == userData.Id {
player.Name = newUsername
updatedPlayer, err := json.Marshal(player)
if err != nil {
Context.Error(err.Error())
return Context.Res.Json(ErrorResponse{
Error: err.Error(),
}, Context.Res.WithStatusCode(500))
}
estimationSession.Players[i] = string(updatedPlayer)
break
}
}
patch := map[string]any{"players": estimationSession.Players}
_, err := databases.UpdateDocument(databaseId, collectionId, estimationSession.Id, databases.WithUpdateDocumentData(patch))
if err != nil {
Context.Error(err.Error())
return Context.Res.Json(ErrorResponse{
Error: err.Error(),
}, Context.Res.WithStatusCode(500))
}
Context.Log("Updated estimation: ", estimationSession.Id)
}
return Context.Res.Json(Response{
Message: "Updated player name",
})
}