appview/pages: improve notification styles #619

merged
opened by oppi.li targeting master from push-spvnpqlqqpkw
Changed files
+103 -39
appview
models
pages
templates
notifications
fragments
+29 -1
appview/models/notifications.go
···
package models
-
import "time"
type NotificationType string
···
PullId *int64
}
type NotificationWithEntity struct {
*Notification
Repo *Repo
···
package models
+
import (
+
"time"
+
)
type NotificationType string
···
PullId *int64
}
+
// lucide icon that represents this notification
+
func (n *Notification) Icon() string {
+
switch n.Type {
+
case NotificationTypeRepoStarred:
+
return "star"
+
case NotificationTypeIssueCreated:
+
return "circle-dot"
+
case NotificationTypeIssueCommented:
+
return "message-square"
+
case NotificationTypeIssueClosed:
+
return "ban"
+
case NotificationTypePullCreated:
+
return "git-pull-request-create"
+
case NotificationTypePullCommented:
+
return "message-square"
+
case NotificationTypePullMerged:
+
return "git-merge"
+
case NotificationTypePullClosed:
+
return "git-pull-request-closed"
+
case NotificationTypeFollowed:
+
return "user-plus"
+
default:
+
return ""
+
}
+
}
+
type NotificationWithEntity struct {
*Notification
Repo *Repo
+64 -14
appview/pages/templates/notifications/fragments/item.html
···
{{define "notifications/fragments/item"}}
-
<div class="border border-gray-200 dark:border-gray-700 rounded-sm p-3 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors {{if not .Read}}bg-blue-50 dark:bg-blue-900/20{{end}}">
-
{{if .Issue}}
-
{{template "issueNotification" .}}
-
{{else if .Pull}}
-
{{template "pullNotification" .}}
-
{{else if .Repo}}
-
{{template "repoNotification" .}}
-
{{else if eq .Type "followed"}}
-
{{template "followNotification" .}}
-
{{else}}
-
{{template "genericNotification" .}}
-
{{end}}
-
</div>
{{end}}
{{define "issueNotification"}}
{{$url := printf "/%s/%s/issues/%d" (resolve .Repo.Did) .Repo.Name .Issue.IssueId}}
<a
···
{{ i "ban" "w-4 h-4" }}
</span>
{{end}}
-
{{template "user/fragments/picHandle" (resolve .ActorDid)}}
{{if eq .Type "issue_created"}}
<span class="text-gray-500 dark:text-gray-400">opened issue</span>
{{else if eq .Type "issue_commented"}}
···
{{define "notifications/fragments/item"}}
+
<div
+
class="
+
w-full mx-auto rounded drop-shadow-sm dark:text-white bg-white dark:bg-gray-800 px-2 md:px-6 py-4 transition-colors
+
{{if not .Read}}bg-blue-50 dark:bg-blue-900/20 border border-blue-500 dark:border-sky-800{{end}}
+
flex gap-2 items-center
+
"
+
>
+
+
{{ template "notificationIcon" . }}
+
<div class="flex-1 w-full flex flex-col gap-1">
+
<span>{{ template "notificationHeader" . }}</span>
+
<span class="text-sm text-gray-500 dark:text-gray-400">{{ template "notificationSummary" . }}</span>
+
</div>
+
+
</div>
{{end}}
+
{{ define "notificationIcon" }}
+
<div class="flex-shrink-0 max-h-full w-16 h-16 relative">
+
<img class="object-cover rounded-full p-2" src="{{ fullAvatar .ActorDid }}" />
+
<div class="absolute border-2 border-white dark:border-gray-800 bg-gray-200 dark:bg-gray-700 bottom-1 right-1 rounded-full p-2 flex items-center justify-center z-10">
+
{{ i .Icon "size-3 text-black dark:text-white" }}
+
</div>
+
</div>
+
{{ end }}
+
+
{{ define "notificationHeader" }}
+
{{ $actor := resolve .ActorDid }}
+
+
<span class="text-black dark:text-white w-fit">{{ $actor }}</span>
+
{{ if eq .Type "repo_starred" }}
+
starred <span class="text-black dark:text-white">{{ resolve .Repo.Did }}/{{ .Repo.Name }}</span>
+
{{ else if eq .Type "issue_created" }}
+
opened an issue
+
{{ else if eq .Type "issue_commented" }}
+
commented on an issue
+
{{ else if eq .Type "issue_closed" }}
+
closed an issue
+
{{ else if eq .Type "pull_created" }}
+
created a pull request
+
{{ else if eq .Type "pull_commented" }}
+
commented on a pull request
+
{{ else if eq .Type "pull_merged" }}
+
merged a pull request
+
{{ else if eq .Type "pull_closed" }}
+
closed a pull request
+
{{ else if eq .Type "followed" }}
+
followed you
+
{{ else }}
+
{{ end }}
+
{{ end }}
+
+
{{ define "notificationSummary" }}
+
{{ if eq .Type "repo_starred" }}
+
<!-- no summary -->
+
{{ else if .Issue }}
+
#{{.Issue.IssueId}} {{.Issue.Title}} on {{resolve .Repo.Did}}/{{.Repo.Name}}
+
{{ else if .Pull }}
+
#{{.Pull.PullId}} {{.Pull.Title}} on {{resolve .Repo.Did}}/{{.Repo.Name}}
+
{{ else if eq .Type "followed" }}
+
<!-- no summary -->
+
{{ else }}
+
{{ end }}
+
{{ end }}
+
{{define "issueNotification"}}
{{$url := printf "/%s/%s/issues/%d" (resolve .Repo.Did) .Repo.Name .Issue.IssueId}}
<a
···
{{ i "ban" "w-4 h-4" }}
</span>
{{end}}
+
{{template "user/fragments/picHandle" .ActorDid}}
{{if eq .Type "issue_created"}}
<span class="text-gray-500 dark:text-gray-400">opened issue</span>
{{else if eq .Type "issue_commented"}}
+10 -24
appview/pages/templates/notifications/list.html
···
{{ define "title" }}notifications{{ end }}
{{ define "content" }}
-
<div class="p-6">
-
<div class="flex items-center justify-between mb-4">
<p class="text-xl font-bold dark:text-white">Notifications</p>
<a href="/settings/notifications" class="flex items-center gap-2">
{{ i "settings" "w-4 h-4" }}
···
</div>
</div>
-
<div class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white">
{{if .Notifications}}
-
<div class="flex flex-col gap-4" id="notifications-list">
{{range .Notifications}}
{{template "notifications/fragments/item" .}}
{{end}}
</div>
-
{{if .HasMore}}
-
<div class="mt-6 text-center">
-
<button
-
class="btn gap-2 group"
-
hx-get="/notifications?offset={{.NextOffset}}&limit={{.Limit}}"
-
hx-target="#notifications-list"
-
hx-swap="beforeend"
-
>
-
{{ i "chevron-down" "w-4 h-4 group-[.htmx-request]:hidden" }}
-
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
-
Load more
-
</button>
-
</div>
-
{{end}}
{{else}}
-
<div class="text-center py-12">
-
<div class="w-16 h-16 mx-auto mb-4 text-gray-300 dark:text-gray-600">
-
{{ i "bell-off" "w-16 h-16" }}
</div>
-
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-2">No notifications</h3>
-
<p class="text-gray-600 dark:text-gray-400">When you receive notifications, they'll appear here.</p>
</div>
{{end}}
-
</div>
{{ end }}
···
{{ define "title" }}notifications{{ end }}
{{ define "content" }}
+
<div class="px-6 py-4">
+
<div class="flex items-center justify-between">
<p class="text-xl font-bold dark:text-white">Notifications</p>
<a href="/settings/notifications" class="flex items-center gap-2">
{{ i "settings" "w-4 h-4" }}
···
</div>
</div>
{{if .Notifications}}
+
<div class="flex flex-col gap-2" id="notifications-list">
{{range .Notifications}}
{{template "notifications/fragments/item" .}}
{{end}}
</div>
{{else}}
+
<div class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white">
+
<div class="text-center py-12">
+
<div class="w-16 h-16 mx-auto mb-4 text-gray-300 dark:text-gray-600">
+
{{ i "bell-off" "w-16 h-16" }}
+
</div>
+
<h3 class="text-lg font-medium text-gray-900 dark:text-white mb-2">No notifications</h3>
+
<p class="text-gray-600 dark:text-gray-400">When you receive notifications, they'll appear here.</p>
</div>
</div>
{{end}}
{{ end }}