Signed-off-by: oppiliappan me@oppi.li
+65
-2
Diff
round #1
+9
appview/db/db.go
+9
appview/db/db.go
···
674
674
foreign key (vouch_id) references vouches(id) on delete cascade
675
675
);
676
676
677
+
create table if not exists vouch_skips (
678
+
did text not null,
679
+
subject_did text not null,
680
+
created_at text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
681
+
primary key (did, subject_did),
682
+
check (did <> subject_did)
683
+
);
684
+
685
+
677
686
create table if not exists migrations (
678
687
id integer primary key autoincrement,
679
688
name text unique
+11
-1
appview/db/vouch.go
+11
-1
appview/db/vouch.go
···
308
308
return batch[subjectDid], nil
309
309
}
310
310
311
+
func SkipVouchSuggestion(e Execer, did, subjectDid string) error {
312
+
_, err := e.Exec(
313
+
`insert or ignore into vouch_skips (did, subject_did) values (?, ?)`,
314
+
did, subjectDid,
315
+
)
316
+
return err
317
+
}
318
+
311
319
// priority:
312
320
// 1. collaborator invites sent
313
321
// 2. knot member invites sent
···
390
398
)
391
399
where did not in (
392
400
select subject_did from vouches where vouches.did = ?
401
+
union
402
+
select subject_did from vouch_skips where vouch_skips.did = ?
393
403
)
394
404
group by did
395
405
order by min(priority) asc, max(created) desc
···
405
415
did, did, // issue_comments
406
416
did, did, // follows
407
417
did, did, // stars
408
-
did, // vouches exclusion
418
+
did, did, // existing vouches + skips exclusion
409
419
limit,
410
420
}
411
421
+11
-1
appview/pages/templates/user/vouches.html
+11
-1
appview/pages/templates/user/vouches.html
···
43
43
{{ if .Suggestions }}
44
44
<div class="flex flex-col gap-2">
45
45
{{ range .Suggestions }}
46
-
<div class="flex items-center gap-3 border border-gray-200 dark:border-gray-700 rounded-sm p-4 bg-white dark:bg-gray-800">
46
+
<div class="flex items-center gap-4 border border-gray-200 dark:border-gray-700 rounded-sm p-4 bg-white dark:bg-gray-800">
47
47
<img src="{{ tinyAvatar .Did.String }}" alt="" class="rounded-full size-10 border border-gray-300 dark:border-gray-700 shrink-0" />
48
48
<div class="flex flex-col gap-0.5 min-w-0 flex-1">
49
49
<a href="/{{ resolve .Did.String }}" class="font-medium hover:underline dark:text-white truncate">{{ resolve .Did.String }}</a>
···
52
52
<div class="shrink-0 w-32">
53
53
{{ template "user/fragments/vouch" . }}
54
54
</div>
55
+
<button
56
+
hx-post="/vouch/skip?subject={{ .Did.String }}"
57
+
hx-trigger="click"
58
+
hx-disabled-elt="this"
59
+
title="Skip suggestion"
60
+
class="group hit-area hit-area-4 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 p-0.5"
61
+
>
62
+
{{ i "x" "size-4 block group-[.htmx-request]:hidden" }}
63
+
{{ i "loader-circle" "size-4 animate-spin hidden group-[.htmx-request]:block" }}
64
+
</button>
55
65
</div>
56
66
{{ end }}
57
67
</div>
+1
appview/state/router.go
+1
appview/state/router.go
+33
appview/state/vouch.go
+33
appview/state/vouch.go
···
14
14
"tangled.org/core/log"
15
15
)
16
16
17
+
func (s *State) SkipVouchSuggestion(w http.ResponseWriter, r *http.Request) {
18
+
l := log.SubLogger(s.logger, "skipVouchSuggestion")
19
+
currentUser := s.oauth.GetMultiAccountUser(r)
20
+
21
+
subject := r.FormValue("subject")
22
+
if subject == "" {
23
+
l.Warn("missing subject")
24
+
s.pages.Notice(w, "error", "Missing subject user.")
25
+
return
26
+
}
27
+
28
+
subjectIdent, err := s.idResolver.ResolveIdent(r.Context(), subject)
29
+
if err != nil {
30
+
l.Error("failed to resolve subject", "subject", subject, "err", err)
31
+
s.pages.Notice(w, "error", "Could not find that user.")
32
+
return
33
+
}
34
+
35
+
if currentUser.Did == subjectIdent.DID.String() {
36
+
l.Warn("cannot skip yourself")
37
+
s.pages.Notice(w, "error", "You cannot skip yourself.")
38
+
return
39
+
}
40
+
41
+
if err := db.SkipVouchSuggestion(s.db, currentUser.Did, subjectIdent.DID.String()); err != nil {
42
+
l.Error("failed to skip vouch suggestion", "err", err)
43
+
s.pages.Notice(w, "error", "Failed to skip suggestion.")
44
+
return
45
+
}
46
+
47
+
s.pages.HxRefresh(w)
48
+
}
49
+
17
50
func (s *State) Vouch(w http.ResponseWriter, r *http.Request) {
18
51
l := log.SubLogger(s.logger, "vouch")
19
52
l = s.logger.With("handler", "Vouch")