tangled
alpha
login
or
join now
lewis.moe
/
tangled-core
1
fork
atom
Monorepo for Tangled
1
fork
atom
overview
issues
1
pulls
pipelines
pages: support MultiAccountUser in templates and params
lewis.moe
1 month ago
ae0a6ddd
d10ddce1
+180
-77
4 changed files
expand all
collapse all
unified
split
appview
pages
funcmap.go
pages.go
templates
layouts
fragments
topbar.html
user
login.html
+10
appview/pages/funcmap.go
···
28
28
emoji "github.com/yuin/goldmark-emoji"
29
29
"tangled.org/core/appview/filetree"
30
30
"tangled.org/core/appview/models"
31
31
+
"tangled.org/core/appview/oauth"
31
32
"tangled.org/core/appview/pages/markup"
32
33
"tangled.org/core/crypto"
33
34
)
···
384
385
return "error"
385
386
}
386
387
return fp
388
388
+
},
389
389
+
"otherAccounts": func(activeDid string, accounts []oauth.AccountInfo) []oauth.AccountInfo {
390
390
+
result := make([]oauth.AccountInfo, 0, len(accounts))
391
391
+
for _, acc := range accounts {
392
392
+
if acc.Did != activeDid {
393
393
+
result = append(result, acc)
394
394
+
}
395
395
+
}
396
396
+
return result
387
397
},
388
398
}
389
399
}
+68
-66
appview/pages/pages.go
···
226
226
}
227
227
228
228
type LoginParams struct {
229
229
-
ReturnUrl string
230
230
-
ErrorCode string
229
229
+
ReturnUrl string
230
230
+
ErrorCode string
231
231
+
AddAccount bool
232
232
+
LoggedInUser *oauth.MultiAccountUser
231
233
}
232
234
233
235
func (p *Pages) Login(w io.Writer, params LoginParams) error {
···
247
249
}
248
250
249
251
type TermsOfServiceParams struct {
250
250
-
LoggedInUser *oauth.User
252
252
+
LoggedInUser *oauth.MultiAccountUser
251
253
Content template.HTML
252
254
}
253
255
···
275
277
}
276
278
277
279
type PrivacyPolicyParams struct {
278
278
-
LoggedInUser *oauth.User
280
280
+
LoggedInUser *oauth.MultiAccountUser
279
281
Content template.HTML
280
282
}
281
283
···
303
305
}
304
306
305
307
type BrandParams struct {
306
306
-
LoggedInUser *oauth.User
308
308
+
LoggedInUser *oauth.MultiAccountUser
307
309
}
308
310
309
311
func (p *Pages) Brand(w io.Writer, params BrandParams) error {
···
311
313
}
312
314
313
315
type TimelineParams struct {
314
314
-
LoggedInUser *oauth.User
316
316
+
LoggedInUser *oauth.MultiAccountUser
315
317
Timeline []models.TimelineEvent
316
318
Repos []models.Repo
317
319
GfiLabel *models.LabelDefinition
···
322
324
}
323
325
324
326
type GoodFirstIssuesParams struct {
325
325
-
LoggedInUser *oauth.User
327
327
+
LoggedInUser *oauth.MultiAccountUser
326
328
Issues []models.Issue
327
329
RepoGroups []*models.RepoGroup
328
330
LabelDefs map[string]*models.LabelDefinition
···
335
337
}
336
338
337
339
type UserProfileSettingsParams struct {
338
338
-
LoggedInUser *oauth.User
340
340
+
LoggedInUser *oauth.MultiAccountUser
339
341
Tabs []map[string]any
340
342
Tab string
341
343
}
···
345
347
}
346
348
347
349
type NotificationsParams struct {
348
348
-
LoggedInUser *oauth.User
350
350
+
LoggedInUser *oauth.MultiAccountUser
349
351
Notifications []*models.NotificationWithEntity
350
352
UnreadCount int
351
353
Page pagination.Page
···
373
375
}
374
376
375
377
type UserKeysSettingsParams struct {
376
376
-
LoggedInUser *oauth.User
378
378
+
LoggedInUser *oauth.MultiAccountUser
377
379
PubKeys []models.PublicKey
378
380
Tabs []map[string]any
379
381
Tab string
···
384
386
}
385
387
386
388
type UserEmailsSettingsParams struct {
387
387
-
LoggedInUser *oauth.User
389
389
+
LoggedInUser *oauth.MultiAccountUser
388
390
Emails []models.Email
389
391
Tabs []map[string]any
390
392
Tab string
···
395
397
}
396
398
397
399
type UserNotificationSettingsParams struct {
398
398
-
LoggedInUser *oauth.User
400
400
+
LoggedInUser *oauth.MultiAccountUser
399
401
Preferences *models.NotificationPreferences
400
402
Tabs []map[string]any
401
403
Tab string
···
415
417
}
416
418
417
419
type KnotsParams struct {
418
418
-
LoggedInUser *oauth.User
420
420
+
LoggedInUser *oauth.MultiAccountUser
419
421
Registrations []models.Registration
420
422
Tabs []map[string]any
421
423
Tab string
···
426
428
}
427
429
428
430
type KnotParams struct {
429
429
-
LoggedInUser *oauth.User
431
431
+
LoggedInUser *oauth.MultiAccountUser
430
432
Registration *models.Registration
431
433
Members []string
432
434
Repos map[string][]models.Repo
···
448
450
}
449
451
450
452
type SpindlesParams struct {
451
451
-
LoggedInUser *oauth.User
453
453
+
LoggedInUser *oauth.MultiAccountUser
452
454
Spindles []models.Spindle
453
455
Tabs []map[string]any
454
456
Tab string
···
469
471
}
470
472
471
473
type SpindleDashboardParams struct {
472
472
-
LoggedInUser *oauth.User
474
474
+
LoggedInUser *oauth.MultiAccountUser
473
475
Spindle models.Spindle
474
476
Members []string
475
477
Repos map[string][]models.Repo
···
482
484
}
483
485
484
486
type NewRepoParams struct {
485
485
-
LoggedInUser *oauth.User
487
487
+
LoggedInUser *oauth.MultiAccountUser
486
488
Knots []string
487
489
}
488
490
···
491
493
}
492
494
493
495
type ForkRepoParams struct {
494
494
-
LoggedInUser *oauth.User
496
496
+
LoggedInUser *oauth.MultiAccountUser
495
497
Knots []string
496
498
RepoInfo repoinfo.RepoInfo
497
499
}
···
529
531
}
530
532
531
533
type ProfileOverviewParams struct {
532
532
-
LoggedInUser *oauth.User
534
534
+
LoggedInUser *oauth.MultiAccountUser
533
535
Repos []models.Repo
534
536
CollaboratingRepos []models.Repo
535
537
ProfileTimeline *models.ProfileTimeline
···
543
545
}
544
546
545
547
type ProfileReposParams struct {
546
546
-
LoggedInUser *oauth.User
548
548
+
LoggedInUser *oauth.MultiAccountUser
547
549
Repos []models.Repo
548
550
Card *ProfileCard
549
551
Active string
···
555
557
}
556
558
557
559
type ProfileStarredParams struct {
558
558
-
LoggedInUser *oauth.User
560
560
+
LoggedInUser *oauth.MultiAccountUser
559
561
Repos []models.Repo
560
562
Card *ProfileCard
561
563
Active string
···
567
569
}
568
570
569
571
type ProfileStringsParams struct {
570
570
-
LoggedInUser *oauth.User
572
572
+
LoggedInUser *oauth.MultiAccountUser
571
573
Strings []models.String
572
574
Card *ProfileCard
573
575
Active string
···
580
582
581
583
type FollowCard struct {
582
584
UserDid string
583
583
-
LoggedInUser *oauth.User
585
585
+
LoggedInUser *oauth.MultiAccountUser
584
586
FollowStatus models.FollowStatus
585
587
FollowersCount int64
586
588
FollowingCount int64
···
588
590
}
589
591
590
592
type ProfileFollowersParams struct {
591
591
-
LoggedInUser *oauth.User
593
593
+
LoggedInUser *oauth.MultiAccountUser
592
594
Followers []FollowCard
593
595
Card *ProfileCard
594
596
Active string
···
600
602
}
601
603
602
604
type ProfileFollowingParams struct {
603
603
-
LoggedInUser *oauth.User
605
605
+
LoggedInUser *oauth.MultiAccountUser
604
606
Following []FollowCard
605
607
Card *ProfileCard
606
608
Active string
···
622
624
}
623
625
624
626
type EditBioParams struct {
625
625
-
LoggedInUser *oauth.User
627
627
+
LoggedInUser *oauth.MultiAccountUser
626
628
Profile *models.Profile
627
629
}
628
630
···
631
633
}
632
634
633
635
type EditPinsParams struct {
634
634
-
LoggedInUser *oauth.User
636
636
+
LoggedInUser *oauth.MultiAccountUser
635
637
Profile *models.Profile
636
638
AllRepos []PinnedRepo
637
639
}
···
658
660
}
659
661
660
662
type RepoIndexParams struct {
661
661
-
LoggedInUser *oauth.User
663
663
+
LoggedInUser *oauth.MultiAccountUser
662
664
RepoInfo repoinfo.RepoInfo
663
665
Active string
664
666
TagMap map[string][]string
···
707
709
}
708
710
709
711
type RepoLogParams struct {
710
710
-
LoggedInUser *oauth.User
712
712
+
LoggedInUser *oauth.MultiAccountUser
711
713
RepoInfo repoinfo.RepoInfo
712
714
TagMap map[string][]string
713
715
Active string
···
724
726
}
725
727
726
728
type RepoCommitParams struct {
727
727
-
LoggedInUser *oauth.User
729
729
+
LoggedInUser *oauth.MultiAccountUser
728
730
RepoInfo repoinfo.RepoInfo
729
731
Active string
730
732
EmailToDid map[string]string
···
743
745
}
744
746
745
747
type RepoTreeParams struct {
746
746
-
LoggedInUser *oauth.User
748
748
+
LoggedInUser *oauth.MultiAccountUser
747
749
RepoInfo repoinfo.RepoInfo
748
750
Active string
749
751
BreadCrumbs [][]string
···
798
800
}
799
801
800
802
type RepoBranchesParams struct {
801
801
-
LoggedInUser *oauth.User
803
803
+
LoggedInUser *oauth.MultiAccountUser
802
804
RepoInfo repoinfo.RepoInfo
803
805
Active string
804
806
types.RepoBranchesResponse
···
810
812
}
811
813
812
814
type RepoTagsParams struct {
813
813
-
LoggedInUser *oauth.User
815
815
+
LoggedInUser *oauth.MultiAccountUser
814
816
RepoInfo repoinfo.RepoInfo
815
817
Active string
816
818
types.RepoTagsResponse
···
824
826
}
825
827
826
828
type RepoArtifactParams struct {
827
827
-
LoggedInUser *oauth.User
829
829
+
LoggedInUser *oauth.MultiAccountUser
828
830
RepoInfo repoinfo.RepoInfo
829
831
Artifact models.Artifact
830
832
}
···
834
836
}
835
837
836
838
type RepoBlobParams struct {
837
837
-
LoggedInUser *oauth.User
839
839
+
LoggedInUser *oauth.MultiAccountUser
838
840
RepoInfo repoinfo.RepoInfo
839
841
Active string
840
842
BreadCrumbs [][]string
···
858
860
}
859
861
860
862
type RepoSettingsParams struct {
861
861
-
LoggedInUser *oauth.User
863
863
+
LoggedInUser *oauth.MultiAccountUser
862
864
RepoInfo repoinfo.RepoInfo
863
865
Collaborators []Collaborator
864
866
Active string
···
877
879
}
878
880
879
881
type RepoGeneralSettingsParams struct {
880
880
-
LoggedInUser *oauth.User
882
882
+
LoggedInUser *oauth.MultiAccountUser
881
883
RepoInfo repoinfo.RepoInfo
882
884
Labels []models.LabelDefinition
883
885
DefaultLabels []models.LabelDefinition
···
895
897
}
896
898
897
899
type RepoAccessSettingsParams struct {
898
898
-
LoggedInUser *oauth.User
900
900
+
LoggedInUser *oauth.MultiAccountUser
899
901
RepoInfo repoinfo.RepoInfo
900
902
Active string
901
903
Tabs []map[string]any
···
909
911
}
910
912
911
913
type RepoPipelineSettingsParams struct {
912
912
-
LoggedInUser *oauth.User
914
914
+
LoggedInUser *oauth.MultiAccountUser
913
915
RepoInfo repoinfo.RepoInfo
914
916
Active string
915
917
Tabs []map[string]any
···
925
927
}
926
928
927
929
type RepoIssuesParams struct {
928
928
-
LoggedInUser *oauth.User
930
930
+
LoggedInUser *oauth.MultiAccountUser
929
931
RepoInfo repoinfo.RepoInfo
930
932
Active string
931
933
Issues []models.Issue
···
942
944
}
943
945
944
946
type RepoSingleIssueParams struct {
945
945
-
LoggedInUser *oauth.User
947
947
+
LoggedInUser *oauth.MultiAccountUser
946
948
RepoInfo repoinfo.RepoInfo
947
949
Active string
948
950
Issue *models.Issue
···
961
963
}
962
964
963
965
type EditIssueParams struct {
964
964
-
LoggedInUser *oauth.User
966
966
+
LoggedInUser *oauth.MultiAccountUser
965
967
RepoInfo repoinfo.RepoInfo
966
968
Issue *models.Issue
967
969
Action string
···
985
987
}
986
988
987
989
type RepoNewIssueParams struct {
988
988
-
LoggedInUser *oauth.User
990
990
+
LoggedInUser *oauth.MultiAccountUser
989
991
RepoInfo repoinfo.RepoInfo
990
992
Issue *models.Issue // existing issue if any -- passed when editing
991
993
Active string
···
999
1001
}
1000
1002
1001
1003
type EditIssueCommentParams struct {
1002
1002
-
LoggedInUser *oauth.User
1004
1004
+
LoggedInUser *oauth.MultiAccountUser
1003
1005
RepoInfo repoinfo.RepoInfo
1004
1006
Issue *models.Issue
1005
1007
Comment *models.IssueComment
···
1010
1012
}
1011
1013
1012
1014
type ReplyIssueCommentPlaceholderParams struct {
1013
1013
-
LoggedInUser *oauth.User
1015
1015
+
LoggedInUser *oauth.MultiAccountUser
1014
1016
RepoInfo repoinfo.RepoInfo
1015
1017
Issue *models.Issue
1016
1018
Comment *models.IssueComment
···
1021
1023
}
1022
1024
1023
1025
type ReplyIssueCommentParams struct {
1024
1024
-
LoggedInUser *oauth.User
1026
1026
+
LoggedInUser *oauth.MultiAccountUser
1025
1027
RepoInfo repoinfo.RepoInfo
1026
1028
Issue *models.Issue
1027
1029
Comment *models.IssueComment
···
1032
1034
}
1033
1035
1034
1036
type IssueCommentBodyParams struct {
1035
1035
-
LoggedInUser *oauth.User
1037
1037
+
LoggedInUser *oauth.MultiAccountUser
1036
1038
RepoInfo repoinfo.RepoInfo
1037
1039
Issue *models.Issue
1038
1040
Comment *models.IssueComment
···
1043
1045
}
1044
1046
1045
1047
type RepoNewPullParams struct {
1046
1046
-
LoggedInUser *oauth.User
1048
1048
+
LoggedInUser *oauth.MultiAccountUser
1047
1049
RepoInfo repoinfo.RepoInfo
1048
1050
Branches []types.Branch
1049
1051
Strategy string
···
1060
1062
}
1061
1063
1062
1064
type RepoPullsParams struct {
1063
1063
-
LoggedInUser *oauth.User
1065
1065
+
LoggedInUser *oauth.MultiAccountUser
1064
1066
RepoInfo repoinfo.RepoInfo
1065
1067
Pulls []*models.Pull
1066
1068
Active string
···
1097
1099
}
1098
1100
1099
1101
type RepoSinglePullParams struct {
1100
1100
-
LoggedInUser *oauth.User
1102
1102
+
LoggedInUser *oauth.MultiAccountUser
1101
1103
RepoInfo repoinfo.RepoInfo
1102
1104
Active string
1103
1105
Pull *models.Pull
···
1122
1124
}
1123
1125
1124
1126
type RepoPullPatchParams struct {
1125
1125
-
LoggedInUser *oauth.User
1127
1127
+
LoggedInUser *oauth.MultiAccountUser
1126
1128
RepoInfo repoinfo.RepoInfo
1127
1129
Pull *models.Pull
1128
1130
Stack models.Stack
···
1139
1141
}
1140
1142
1141
1143
type RepoPullInterdiffParams struct {
1142
1142
-
LoggedInUser *oauth.User
1144
1144
+
LoggedInUser *oauth.MultiAccountUser
1143
1145
RepoInfo repoinfo.RepoInfo
1144
1146
Pull *models.Pull
1145
1147
Round int
···
1192
1194
}
1193
1195
1194
1196
type PullResubmitParams struct {
1195
1195
-
LoggedInUser *oauth.User
1197
1197
+
LoggedInUser *oauth.MultiAccountUser
1196
1198
RepoInfo repoinfo.RepoInfo
1197
1199
Pull *models.Pull
1198
1200
SubmissionId int
···
1203
1205
}
1204
1206
1205
1207
type PullActionsParams struct {
1206
1206
-
LoggedInUser *oauth.User
1208
1208
+
LoggedInUser *oauth.MultiAccountUser
1207
1209
RepoInfo repoinfo.RepoInfo
1208
1210
Pull *models.Pull
1209
1211
RoundNumber int
···
1218
1220
}
1219
1221
1220
1222
type PullNewCommentParams struct {
1221
1221
-
LoggedInUser *oauth.User
1223
1223
+
LoggedInUser *oauth.MultiAccountUser
1222
1224
RepoInfo repoinfo.RepoInfo
1223
1225
Pull *models.Pull
1224
1226
RoundNumber int
···
1229
1231
}
1230
1232
1231
1233
type RepoCompareParams struct {
1232
1232
-
LoggedInUser *oauth.User
1234
1234
+
LoggedInUser *oauth.MultiAccountUser
1233
1235
RepoInfo repoinfo.RepoInfo
1234
1236
Forks []models.Repo
1235
1237
Branches []types.Branch
···
1248
1250
}
1249
1251
1250
1252
type RepoCompareNewParams struct {
1251
1251
-
LoggedInUser *oauth.User
1253
1253
+
LoggedInUser *oauth.MultiAccountUser
1252
1254
RepoInfo repoinfo.RepoInfo
1253
1255
Forks []models.Repo
1254
1256
Branches []types.Branch
···
1265
1267
}
1266
1268
1267
1269
type RepoCompareAllowPullParams struct {
1268
1268
-
LoggedInUser *oauth.User
1270
1270
+
LoggedInUser *oauth.MultiAccountUser
1269
1271
RepoInfo repoinfo.RepoInfo
1270
1272
Base string
1271
1273
Head string
···
1285
1287
}
1286
1288
1287
1289
type LabelPanelParams struct {
1288
1288
-
LoggedInUser *oauth.User
1290
1290
+
LoggedInUser *oauth.MultiAccountUser
1289
1291
RepoInfo repoinfo.RepoInfo
1290
1292
Defs map[string]*models.LabelDefinition
1291
1293
Subject string
···
1297
1299
}
1298
1300
1299
1301
type EditLabelPanelParams struct {
1300
1300
-
LoggedInUser *oauth.User
1302
1302
+
LoggedInUser *oauth.MultiAccountUser
1301
1303
RepoInfo repoinfo.RepoInfo
1302
1304
Defs map[string]*models.LabelDefinition
1303
1305
Subject string
···
1309
1311
}
1310
1312
1311
1313
type PipelinesParams struct {
1312
1312
-
LoggedInUser *oauth.User
1314
1314
+
LoggedInUser *oauth.MultiAccountUser
1313
1315
RepoInfo repoinfo.RepoInfo
1314
1316
Pipelines []models.Pipeline
1315
1317
Active string
···
1352
1354
}
1353
1355
1354
1356
type WorkflowParams struct {
1355
1355
-
LoggedInUser *oauth.User
1357
1357
+
LoggedInUser *oauth.MultiAccountUser
1356
1358
RepoInfo repoinfo.RepoInfo
1357
1359
Pipeline models.Pipeline
1358
1360
Workflow string
···
1366
1368
}
1367
1369
1368
1370
type PutStringParams struct {
1369
1369
-
LoggedInUser *oauth.User
1371
1371
+
LoggedInUser *oauth.MultiAccountUser
1370
1372
Action string
1371
1373
1372
1374
// this is supplied in the case of editing an existing string
···
1378
1380
}
1379
1381
1380
1382
type StringsDashboardParams struct {
1381
1381
-
LoggedInUser *oauth.User
1383
1383
+
LoggedInUser *oauth.MultiAccountUser
1382
1384
Card ProfileCard
1383
1385
Strings []models.String
1384
1386
}
···
1388
1390
}
1389
1391
1390
1392
type StringTimelineParams struct {
1391
1391
-
LoggedInUser *oauth.User
1393
1393
+
LoggedInUser *oauth.MultiAccountUser
1392
1394
Strings []models.String
1393
1395
}
1394
1396
···
1397
1399
}
1398
1400
1399
1401
type SingleStringParams struct {
1400
1400
-
LoggedInUser *oauth.User
1402
1402
+
LoggedInUser *oauth.MultiAccountUser
1401
1403
ShowRendered bool
1402
1404
RenderToggle bool
1403
1405
RenderedContents template.HTML
+49
-11
appview/pages/templates/layouts/fragments/topbar.html
···
45
45
{{ define "profileDropdown" }}
46
46
<details class="relative inline-block text-left nav-dropdown">
47
47
<summary class="cursor-pointer list-none flex items-center gap-1">
48
48
-
{{ $user := .Did }}
48
48
+
{{ $user := .Active.Did }}
49
49
<img
50
50
src="{{ tinyAvatar $user }}"
51
51
alt=""
···
53
53
/>
54
54
<span class="hidden md:inline">{{ $user | resolve | truncateAt30 }}</span>
55
55
</summary>
56
56
-
<div class="absolute flex flex-col right-0 mt-4 p-4 rounded w-48 bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700">
57
57
-
<a href="/{{ $user }}">profile</a>
58
58
-
<a href="/{{ $user }}?tab=repos">repositories</a>
59
59
-
<a href="/{{ $user }}?tab=strings">strings</a>
60
60
-
<a href="/settings">settings</a>
61
61
-
<a href="#"
62
62
-
hx-post="/logout"
63
63
-
hx-swap="none"
64
64
-
class="text-red-400 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300">
65
65
-
logout
56
56
+
<div class="absolute right-0 mt-4 p-4 rounded bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700 shadow-lg z-50" style="width: 14rem;">
57
57
+
{{ $active := .Active.Did }}
58
58
+
59
59
+
<div class="pb-2 mb-2 border-b border-gray-200 dark:border-gray-700">
60
60
+
<div class="flex items-center gap-2">
61
61
+
<img src="{{ tinyAvatar $active }}" alt="" class="rounded-full h-8 w-8 flex-shrink-0 border border-gray-300 dark:border-gray-700" />
62
62
+
<div class="flex-1 overflow-hidden">
63
63
+
<p class="font-medium text-sm truncate">{{ $active | resolve }}</p>
64
64
+
<p class="text-xs text-green-600 dark:text-green-400">active</p>
65
65
+
</div>
66
66
+
</div>
67
67
+
</div>
68
68
+
69
69
+
{{ $others := .Accounts | otherAccounts $active }}
70
70
+
{{ if $others }}
71
71
+
<div class="pb-2 mb-2 border-b border-gray-200 dark:border-gray-700">
72
72
+
<p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-1">Switch Account</p>
73
73
+
{{ range $others }}
74
74
+
<button
75
75
+
type="button"
76
76
+
hx-post="/account/switch"
77
77
+
hx-vals='{"did": "{{ .Did }}"}'
78
78
+
hx-swap="none"
79
79
+
class="flex items-center gap-2 w-full py-1.5 rounded hover:bg-gray-100 dark:hover:bg-gray-700 text-left"
80
80
+
>
81
81
+
<img src="{{ tinyAvatar .Did }}" alt="" class="rounded-full h-6 w-6 flex-shrink-0 border border-gray-300 dark:border-gray-700" />
82
82
+
<span class="text-sm truncate flex-1">{{ .Did | resolve }}</span>
83
83
+
</button>
84
84
+
{{ end }}
85
85
+
</div>
86
86
+
{{ end }}
87
87
+
88
88
+
<a href="/login?mode=add_account" class="flex items-center gap-2 py-1 text-sm">
89
89
+
{{ i "plus" "w-4 h-4 flex-shrink-0" }}
90
90
+
<span>Add another account</span>
66
91
</a>
92
92
+
93
93
+
<div class="pt-2 mt-2 border-t border-gray-200 dark:border-gray-700 space-y-1">
94
94
+
<a href="/{{ $active }}" class="block py-1 text-sm">profile</a>
95
95
+
<a href="/{{ $active }}?tab=repos" class="block py-1 text-sm">repositories</a>
96
96
+
<a href="/{{ $active }}?tab=strings" class="block py-1 text-sm">strings</a>
97
97
+
<a href="/settings" class="block py-1 text-sm">settings</a>
98
98
+
<a href="#"
99
99
+
hx-post="/logout"
100
100
+
hx-swap="none"
101
101
+
class="block py-1 text-sm text-red-400 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300">
102
102
+
logout
103
103
+
</a>
104
104
+
</div>
67
105
</div>
68
106
</details>
69
107
+53
appview/pages/templates/user/login.html
···
20
20
<h2 class="text-center text-xl italic dark:text-white">
21
21
tightly-knit social coding.
22
22
</h2>
23
23
+
24
24
+
{{ if .AddAccount }}
25
25
+
<div class="flex gap-2 my-4 bg-blue-50 dark:bg-blue-900/30 border border-blue-300 dark:border-sky-800 rounded px-3 py-2 text-blue-600 dark:text-blue-300">
26
26
+
<span class="py-1">{{ i "user-plus" "w-4 h-4" }}</span>
27
27
+
<div>
28
28
+
<h5 class="font-medium">Add another account</h5>
29
29
+
<p class="text-sm">Sign in with a different account to add it to your account list.</p>
30
30
+
</div>
31
31
+
</div>
32
32
+
{{ end }}
33
33
+
34
34
+
{{ if and .LoggedInUser .LoggedInUser.Accounts }}
35
35
+
{{ $accounts := .LoggedInUser.Accounts }}
36
36
+
{{ if $accounts }}
37
37
+
<div class="my-4 border border-gray-200 dark:border-gray-700 rounded overflow-hidden">
38
38
+
<div class="px-3 py-2 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
39
39
+
<span class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide font-medium">Saved accounts</span>
40
40
+
</div>
41
41
+
<div class="divide-y divide-gray-200 dark:divide-gray-700">
42
42
+
{{ range $accounts }}
43
43
+
<div class="flex items-center justify-between px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700">
44
44
+
<button
45
45
+
type="button"
46
46
+
hx-post="/account/switch"
47
47
+
hx-vals='{"did": "{{ .Did }}"}'
48
48
+
hx-swap="none"
49
49
+
class="flex items-center gap-2 flex-1 text-left min-w-0"
50
50
+
>
51
51
+
<img src="{{ tinyAvatar .Did }}" alt="" class="rounded-full h-8 w-8 flex-shrink-0 border border-gray-300 dark:border-gray-700" />
52
52
+
<div class="flex flex-col min-w-0">
53
53
+
<span class="text-sm font-medium dark:text-white truncate">{{ .Did | resolve | truncateAt30 }}</span>
54
54
+
<span class="text-xs text-gray-500 dark:text-gray-400">Click to switch</span>
55
55
+
</div>
56
56
+
</button>
57
57
+
<button
58
58
+
type="button"
59
59
+
hx-delete="/account/{{ .Did }}"
60
60
+
hx-swap="none"
61
61
+
class="p-1 text-gray-400 hover:text-red-500 dark:hover:text-red-400 flex-shrink-0"
62
62
+
title="Remove account"
63
63
+
>
64
64
+
{{ i "x" "w-4 h-4" }}
65
65
+
</button>
66
66
+
</div>
67
67
+
{{ end }}
68
68
+
</div>
69
69
+
</div>
70
70
+
{{ end }}
71
71
+
{{ end }}
72
72
+
23
73
<form
24
74
class="mt-4"
25
75
hx-post="/login"
···
46
96
</span>
47
97
</div>
48
98
<input type="hidden" name="return_url" value="{{ .ReturnUrl }}">
99
99
+
<input type="hidden" name="add_account" value="{{ if .AddAccount }}true{{ end }}">
49
100
50
101
<button
51
102
class="btn w-full my-2 mt-6 text-base "
···
66
117
You have not authorized the app.
67
118
{{ else if eq .ErrorCode "session" }}
68
119
Server failed to create user session.
120
120
+
{{ else if eq .ErrorCode "max_accounts" }}
121
121
+
You have reached the maximum of 20 linked accounts. Please remove an account before adding a new one.
69
122
{{ else }}
70
123
Internal Server error.
71
124
{{ end }}