+7
appview/db/db.go
+7
appview/db/db.go
···
1174
1174
return err
1175
1175
})
1176
1176
1177
+
runMigration(conn, logger, "add-default-knot-profile", func(tx *sql.Tx) error {
1178
+
_, err := tx.Exec(`
1179
+
alter table profile add column default_knot text;
1180
+
`)
1181
+
return err
1182
+
})
1183
+
1177
1184
return &DB{
1178
1185
db,
1179
1186
logger,
+11
-4
appview/db/profile.go
+11
-4
appview/db/profile.go
···
130
130
description,
131
131
include_bluesky,
132
132
location,
133
-
pronouns
133
+
pronouns,
134
+
default_knot
134
135
)
135
-
values (?, ?, ?, ?, ?)`,
136
+
values (?, ?, ?, ?, ?, ?)`,
136
137
profile.Did,
137
138
profile.Description,
138
139
includeBskyValue,
139
140
profile.Location,
140
141
profile.Pronouns,
142
+
profile.DefaultKnot,
141
143
)
142
144
143
145
if err != nil {
···
311
313
func GetProfile(e Execer, did string) (*models.Profile, error) {
312
314
var profile models.Profile
313
315
var pronouns sql.Null[string]
316
+
var defaultKnot sql.Null[string]
314
317
315
318
profile.Did = did
316
319
317
320
includeBluesky := 0
318
321
319
322
err := e.QueryRow(
320
-
`select description, include_bluesky, location, pronouns from profile where did = ?`,
323
+
`select description, include_bluesky, location, pronouns, default_knot from profile where did = ?`,
321
324
did,
322
-
).Scan(&profile.Description, &includeBluesky, &profile.Location, &pronouns)
325
+
).Scan(&profile.Description, &includeBluesky, &profile.Location, &pronouns, &defaultKnot)
323
326
if err == sql.ErrNoRows {
324
327
profile := models.Profile{}
325
328
profile.Did = did
···
336
339
337
340
if pronouns.Valid {
338
341
profile.Pronouns = pronouns.V
342
+
}
343
+
344
+
if defaultKnot.Valid {
345
+
profile.DefaultKnot = defaultKnot.V
339
346
}
340
347
341
348
rows, err := e.Query(`select link from profile_links where did = ?`, did)
+10
appview/knots/knots.go
+10
appview/knots/knots.go
···
80
80
return
81
81
}
82
82
83
+
defaultKnot := ""
84
+
profile, err := db.GetProfile(k.Db, user.Did)
85
+
if err != nil {
86
+
k.Logger.Warn("gettings user profile to get default knot", "error", err)
87
+
}
88
+
if profile != nil {
89
+
defaultKnot = profile.DefaultKnot
90
+
}
91
+
83
92
k.Pages.Knots(w, pages.KnotsParams{
84
93
LoggedInUser: user,
85
94
Registrations: registrations,
86
95
Tabs: knotsTabs,
87
96
Tab: "knots",
97
+
DefaultKnot: defaultKnot,
88
98
})
89
99
}
90
100
+1
appview/models/profile.go
+1
appview/models/profile.go
+3
appview/pages/pages.go
+3
appview/pages/pages.go
···
409
409
Registrations []models.Registration
410
410
Tabs []map[string]any
411
411
Tab string
412
+
DefaultKnot string
412
413
}
413
414
414
415
func (p *Pages) Knots(w io.Writer, params KnotsParams) error {
···
474
475
type NewRepoParams struct {
475
476
LoggedInUser *oauth.User
476
477
Knots []string
478
+
DefaultKnot string
477
479
}
478
480
479
481
func (p *Pages) NewRepo(w io.Writer, params NewRepoParams) error {
···
484
486
LoggedInUser *oauth.User
485
487
Knots []string
486
488
RepoInfo repoinfo.RepoInfo
489
+
DefaultKnot string
487
490
}
488
491
489
492
func (p *Pages) ForkRepo(w io.Writer, params ForkRepoParams) error {
+24
appview/pages/templates/knots/index.html
+24
appview/pages/templates/knots/index.html
···
31
31
<div class="flex flex-col gap-6">
32
32
{{ block "list" . }} {{ end }}
33
33
{{ block "register" . }} {{ end }}
34
+
{{ block "default-knot" . }} {{ end }}
34
35
</div>
35
36
</section>
36
37
{{ end }}
···
59
60
{{ end }}
60
61
</div>
61
62
<div id="operation-error" class="text-red-500 dark:text-red-400"></div>
63
+
</section>
64
+
{{ end }}
65
+
66
+
{{ define "default-knot" }}
67
+
<section class="rounded w-full flex flex-col gap-2">
68
+
<h2 class="text-sm font-bold py-2 uppercase dark:text-gray-300">default knot</h2>
69
+
<select id="default-knot" name="default-knot"
70
+
class="p-1 max-w-64 border border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"
71
+
hx-post="/profile/default-knot"
72
+
hx-swap="none"
73
+
name="default-knot">
74
+
<option value="" >
75
+
Choose a default Knot
76
+
</option>
77
+
<option value="knot1.tangled.sh" {{if eq $.DefaultKnot "knot1.tangled.sh"}}selected{{end}} >
78
+
knot1.tangled.sh
79
+
</option>
80
+
{{ range $registration := .Registrations }}
81
+
<option value="{{ .Domain }}" class="py-1" {{if eq $.DefaultKnot .Domain}}selected{{end}}>
82
+
{{ .Domain }}
83
+
</option>
84
+
{{ end }}
85
+
</select>
62
86
</section>
63
87
{{ end }}
64
88
+3
-1
appview/pages/templates/repo/fork.html
+3
-1
appview/pages/templates/repo/fork.html
···
25
25
value="{{ . }}"
26
26
class="mr-2"
27
27
id="domain-{{ . }}"
28
-
{{if eq (len $.Knots) 1}}checked{{end}}
28
+
{{if eq (len $.Knots) 1}}checked
29
+
{{else if eq $.DefaultKnot . }}checked
30
+
{{end}}
29
31
/>
30
32
<label for="domain-{{ . }}" class="dark:text-white">{{ . }}</label>
31
33
</div>
+3
-1
appview/pages/templates/repo/new.html
+3
-1
appview/pages/templates/repo/new.html
···
155
155
class="mr-2"
156
156
id="domain-{{ . }}"
157
157
required
158
-
{{if eq (len $.Knots) 1}}checked{{end}}
158
+
{{if eq (len $.Knots) 1}}checked
159
+
{{else if eq $.DefaultKnot . }}checked
160
+
{{end}}
159
161
/>
160
162
<label for="domain-{{ . }}" class="dark:text-white lowercase">{{ . }}</label>
161
163
</div>
+10
appview/repo/repo.go
+10
appview/repo/repo.go
···
1003
1003
return
1004
1004
}
1005
1005
1006
+
defaultKnot := ""
1007
+
profile, err := db.GetProfile(rp.db, user.Did)
1008
+
if err != nil {
1009
+
rp.logger.Warn("gettings user profile to get default knot", "error", err)
1010
+
}
1011
+
if profile != nil {
1012
+
defaultKnot = profile.DefaultKnot
1013
+
}
1014
+
1006
1015
rp.pages.ForkRepo(w, pages.ForkRepoParams{
1007
1016
LoggedInUser: user,
1008
1017
Knots: knots,
1009
1018
RepoInfo: rp.repoResolver.GetRepoInfo(r, user),
1019
+
DefaultKnot: defaultKnot,
1010
1020
})
1011
1021
1012
1022
case http.MethodPost:
+32
appview/state/profile.go
+32
appview/state/profile.go
···
613
613
s.updateProfile(profile, w, r)
614
614
}
615
615
616
+
func (s *State) UpdateProfileDefaultKnot(w http.ResponseWriter, r *http.Request) {
617
+
err := r.ParseForm()
618
+
if err != nil {
619
+
log.Println("invalid profile update form", err)
620
+
return
621
+
}
622
+
user := s.oauth.GetUser(r)
623
+
624
+
profile, err := db.GetProfile(s.db, user.Did)
625
+
if err != nil {
626
+
log.Printf("getting profile data for %s: %s", user.Did, err)
627
+
}
628
+
629
+
if profile == nil {
630
+
return
631
+
}
632
+
633
+
profile.DefaultKnot = r.Form.Get("default-knot")
634
+
635
+
tx, err := s.db.BeginTx(r.Context(), nil)
636
+
if err != nil {
637
+
log.Println("failed to start transaction", err)
638
+
return
639
+
}
640
+
641
+
err = db.UpsertProfile(tx, profile)
642
+
if err != nil {
643
+
log.Println("failed to update profile", err)
644
+
return
645
+
}
646
+
}
647
+
616
648
func (s *State) updateProfile(profile *models.Profile, w http.ResponseWriter, r *http.Request) {
617
649
user := s.oauth.GetUser(r)
618
650
tx, err := s.db.BeginTx(r.Context(), nil)
+1
appview/state/router.go
+1
appview/state/router.go
+10
appview/state/state.go
+10
appview/state/state.go
···
453
453
return
454
454
}
455
455
456
+
defaultKnot := ""
457
+
profile, err := db.GetProfile(s.db, user.Did)
458
+
if err != nil {
459
+
s.logger.Warn("gettings user profile to get default knot", "error", err)
460
+
}
461
+
if profile != nil {
462
+
defaultKnot = profile.DefaultKnot
463
+
}
464
+
456
465
s.pages.NewRepo(w, pages.NewRepoParams{
457
466
LoggedInUser: user,
458
467
Knots: knots,
468
+
DefaultKnot: defaultKnot,
459
469
})
460
470
461
471
case http.MethodPost: