153 lines
4.9 KiB
Go
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
|
|
}
|