Files
moteva/server/internal/logic/sharing_mapper.go
T

153 lines
4.9 KiB
Go

package logic
import (
"context"
"errors"
"strings"
"img_infinite_canvas/internal/domain/design"
sharingmodule "img_infinite_canvas/internal/modules/sharing"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func ownedShareProject(ctx context.Context, svcCtx *svc.ServiceContext, projectID string) (design.Project, error) {
return svcCtx.DesignService.GetProject(ctx, strings.TrimSpace(projectID))
}
func verifiedShareOwner(ctx context.Context, svcCtx *svc.ServiceContext, project design.Project) (sharingmodule.Actor, error) {
if svcCtx.AuthService == nil {
return sharingmodule.Actor{}, errors.New("auth service is required for share management")
}
profile, err := svcCtx.AuthService.GetProfile(ctx, project.UserID)
if err != nil {
return sharingmodule.Actor{}, err
}
return sharingmodule.Actor{
Authenticated: true,
UserID: project.UserID,
Email: profile.Email,
CountryCode: profile.CountryCode,
Phone: profile.Phone,
Name: profile.Name,
AvatarURL: profile.AvatarURL,
}, nil
}
func toShareSettingsResponse(ctx context.Context, svcCtx *svc.ServiceContext, project design.Project, settings sharingmodule.Settings) *types.ShareSettingsResponse {
owner := types.SharePerson{
Id: project.UserID,
UserId: project.UserID,
Name: "Owner",
Permission: string(sharingmodule.PermissionOwner),
}
ownerActor, ownerErr := verifiedShareOwner(ctx, svcCtx, project)
if ownerErr == nil {
owner.Name = firstShareIdentifier(ownerActor.Name, owner.Name)
owner.AvatarUrl = ownerActor.AvatarURL
owner.Identifier = firstShareIdentifier(ownerActor.Email, displayPhone(ownerActor.CountryCode, ownerActor.Phone))
}
visibleMembers := filterShareMembers(settings.Members, ownerActor)
members := make([]types.SharePerson, 0, len(visibleMembers))
for _, member := range visibleMembers {
members = append(members, types.SharePerson{
Id: member.ID,
Name: member.Identifier,
Identifier: member.Identifier,
Permission: string(member.Permission),
CreatedAt: formatTime(member.CreatedAt),
})
}
return &types.ShareSettingsResponse{Settings: types.ShareSettings{
ProjectId: project.ID,
ShareId: settings.ShareID,
LinkPermission: string(settings.LinkPermission),
Owner: owner,
Members: members,
VisitorCount: settings.VisitorCount,
UpdatedAt: formatTime(settings.UpdatedAt),
}}
}
func filterShareMembers(members []sharingmodule.Member, owner sharingmodule.Actor) []sharingmodule.Member {
if owner.UserID == "" {
return members
}
filtered := make([]sharingmodule.Member, 0, len(members))
for _, member := range members {
if sharingmodule.ActorOwnsIdentifier(owner, member.Identifier) {
continue
}
filtered = append(filtered, member)
}
return filtered
}
func toShareVisitorsResponse(ctx context.Context, svcCtx *svc.ServiceContext, visits []sharingmodule.VisitRecord) *types.ShareVisitorsResponse {
items := make([]types.ShareVisitor, 0, len(visits))
for _, visit := range visits {
item := types.ShareVisitor{
Id: visit.ID,
UserId: visit.UserID,
Name: "Anonymous visitor",
VisitCount: visit.VisitCount,
LastSeenAt: formatTime(visit.LastSeenAt),
}
if visit.UserID != "" && svcCtx.AuthService != nil {
if profile, err := svcCtx.AuthService.GetProfile(ctx, visit.UserID); err == nil {
item.Name = firstShareIdentifier(profile.Name, profile.Email, displayPhone(profile.CountryCode, profile.Phone), "Visitor")
item.Identifier = firstShareIdentifier(profile.Email, displayPhone(profile.CountryCode, profile.Phone))
item.AvatarUrl = profile.AvatarURL
}
}
items = append(items, item)
}
return &types.ShareVisitorsResponse{Visitors: items}
}
func toShareAccess(access sharingmodule.Access) types.ShareAccess {
return types.ShareAccess{
Permission: string(access.Permission),
Source: access.Source,
Authenticated: access.Authenticated,
IsOwner: access.IsOwner,
Capabilities: types.ShareCapabilities{
CanViewCanvas: access.Capabilities.CanViewCanvas,
CanViewChat: access.Capabilities.CanViewChat,
CanEdit: access.Capabilities.CanEdit,
CanManage: access.Capabilities.CanManage,
},
}
}
func filterSharedProject(project design.Project, access sharingmodule.Access) design.Project {
project.UserID = ""
if !access.Capabilities.CanViewChat {
project.Brief = ""
project.LastThreadID = ""
project.Messages = []design.Message{}
}
return project
}
func firstShareIdentifier(values ...string) string {
for _, value := range values {
if value = strings.TrimSpace(value); value != "" {
return value
}
}
return ""
}
func displayPhone(countryCode string, phone string) string {
phone = strings.TrimSpace(phone)
if phone == "" {
return ""
}
countryCode = strings.TrimPrefix(strings.TrimSpace(countryCode), "+")
if countryCode == "" || strings.HasPrefix(phone, "+") {
return phone
}
return "+" + countryCode + phone
}