Add button and query to delete a List

This commit is contained in:
Alessio 2024-02-25 21:58:56 -08:00
parent 66b32e4c6f
commit 38495e8591
7 changed files with 81 additions and 34 deletions

View File

@ -69,14 +69,26 @@ func (app *Application) ListDetailUsers(w http.ResponseWriter, r *http.Request)
app.buffered_render_page(w, "tpl/list.tpl", PageGlobalData{TweetTrove: trove}, data) app.buffered_render_page(w, "tpl/list.tpl", PageGlobalData{TweetTrove: trove}, data)
} }
func (app *Application) ListDelete(w http.ResponseWriter, r *http.Request) {
list := get_list_from_context(r.Context())
app.Profile.DeleteList(list.ID)
http.Redirect(w, r, "/lists", 302)
}
func (app *Application) ListDetail(w http.ResponseWriter, r *http.Request) { func (app *Application) ListDetail(w http.ResponseWriter, r *http.Request) {
app.traceLog.Printf("'ListDetail' handler (path: %q)", r.URL.Path) app.traceLog.Printf("'ListDetail' handler (path: %q)", r.URL.Path)
parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/") parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
if len(parts) == 1 && parts[0] == "" { if len(parts) == 1 && parts[0] == "" {
switch r.Method {
case "DELETE":
app.ListDelete(w, r)
default:
// No further path; just show the feed // No further path; just show the feed
app.ListDetailFeed(w, r) app.ListDetailFeed(w, r)
} }
return
}
switch parts[0] { switch parts[0] {
case "users": case "users":

View File

@ -693,30 +693,32 @@ ul.space-participants-list li {
} }
.users-list-preview { .users-list-preview {
cursor: pointer; padding: 0.5em 1em;
display: flex;
font-size: 1.5em;
border-color: var(--color-twitter-off-white-dark); border-color: var(--color-twitter-off-white-dark);
border-bottom-style: solid; border-bottom-style: solid;
border-width: 1px; border-width: 1px;
padding: 0.5em 1em;
align-items: center;
} }
.users-list-preview span.num-users { .users-list-preview .list-info-container{
display: flex;
align-items: center;
font-size: 1.5em;
cursor: pointer;
}
.users-list-preview .list-info-container span.num-users {
margin-left: 1em; margin-left: 1em;
color: var(--color-twitter-text-gray); color: var(--color-twitter-text-gray);
} }
.users-list-preview .first-N-profile-images { .users-list-preview .list-info-container .first-N-profile-images {
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
margin-left: 1.5em; margin-left: 1.5em;
} }
.users-list-preview .first-N-profile-images a { .users-list-preview .list-info-container .first-N-profile-images a {
margin-right: -1.2em; margin-right: -1.2em;
line-height: 0; /* TODO: This is duplicated from `.author-info a` and possibly others */ line-height: 0; /* TODO: This is duplicated from `.author-info a` and possibly others */
} }
.users-list-preview .first-N-profile-images .ellipsis { .users-list-preview .list-info-container .first-N-profile-images .ellipsis {
margin-left: 1.5em; margin-left: 1.5em;
} }

View File

@ -17,7 +17,8 @@
<div class="users-list-previews"> <div class="users-list-previews">
{{range .}} {{range .}}
{{$max_display_users := 10}} {{$max_display_users := 10}}
<div class="users-list-preview" hx-get="/lists/{{.ID}}" hx-trigger="click" hx-target="body" hx-push-url="true"> <div class="users-list-preview row spread">
<div class="list-info-container" hx-get="/lists/{{.ID}}" hx-trigger="click" hx-target="body" hx-push-url="true">
<span class="list-name">{{.Name}}</span> <span class="list-name">{{.Name}}</span>
<span class="num-users">({{(len .Users)}})</span> <span class="num-users">({{(len .Users)}})</span>
<div class="first-N-profile-images" hx-trigger="click consume"> <div class="first-N-profile-images" hx-trigger="click consume">
@ -41,6 +42,11 @@
{{end}} {{end}}
</div> </div>
</div> </div>
<a class="unstyled-link quick-link danger"
hx-delete="/lists/{{.ID}}" hx-target="body"
onclick="return confirm('Delete this list? Are you sure?')"
>Delete</a>
</div>
{{end}} {{end}}
</div> </div>
{{end}} {{end}}

View File

@ -53,6 +53,13 @@ func (p Profile) SaveList(l *List) {
} }
} }
func (p Profile) DeleteList(list_id ListID) {
_, err := p.DB.Exec(`delete from lists where rowid = ?`, list_id)
if err != nil {
panic(fmt.Errorf("Error executing DeleteList(%d):\n %w", list_id, err).Error())
}
}
func (p Profile) SaveListUsers(list_id ListID, trove TweetTrove) { func (p Profile) SaveListUsers(list_id ListID, trove TweetTrove) {
for user_id := range trove.Users { for user_id := range trove.Users {
p.SaveListUser(list_id, user_id) p.SaveListUser(list_id, user_id)

View File

@ -173,3 +173,23 @@ func TestGetAllLists(t *testing.T) {
assert.True(len(lists) > 1) // Should be at least Offline Follows and `l` assert.True(len(lists) > 1) // Should be at least Offline Follows and `l`
assert.Contains(lists, l) assert.Contains(lists, l)
} }
func TestDeleteList(t *testing.T) {
require := require.New(t)
profile, err := persistence.LoadProfile("../../sample_data/profile")
require.NoError(err)
// Create an offline list
l := List{IsOnline: false, Name: fmt.Sprintf("Test List %d", rand.Int())}
require.Equal(l.ID, ListID(0))
profile.SaveList(&l)
require.NotEqual(l.ID, ListID(0)) // ID should be assigned when it's saved
// Delete it
profile.DeleteList(l.ID)
// Check it's gone
_, err = profile.GetListById(l.ID)
require.Error(err)
}

View File

@ -43,7 +43,7 @@ create table list_users(rowid integer primary key,
list_id integer not null, list_id integer not null,
user_id integer not null, user_id integer not null,
unique(list_id, user_id) unique(list_id, user_id)
foreign key(list_id) references lists(rowid) foreign key(list_id) references lists(rowid) on delete cascade
foreign key(user_id) references users(id) foreign key(user_id) references users(id)
); );
create index if not exists index_list_users_list_id on list_users (list_id); create index if not exists index_list_users_list_id on list_users (list_id);

View File

@ -66,7 +66,7 @@ create table list_users(rowid integer primary key,
list_id integer not null, list_id integer not null,
user_id integer not null, user_id integer not null,
unique(list_id, user_id) unique(list_id, user_id)
foreign key(list_id) references lists(rowid) foreign key(list_id) references lists(rowid) on delete cascade
foreign key(user_id) references users(id) foreign key(user_id) references users(id)
); );
create index if not exists index_list_users_list_id on list_users (list_id); create index if not exists index_list_users_list_id on list_users (list_id);