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
··· 1 package models 2 3 - import "time" 4 5 type NotificationType string 6 ··· 32 PullId *int64 33 } 34 35 type NotificationWithEntity struct { 36 *Notification 37 Repo *Repo
··· 1 package models 2 3 + import ( 4 + "time" 5 + ) 6 7 type NotificationType string 8 ··· 34 PullId *int64 35 } 36 37 + // lucide icon that represents this notification 38 + func (n *Notification) Icon() string { 39 + switch n.Type { 40 + case NotificationTypeRepoStarred: 41 + return "star" 42 + case NotificationTypeIssueCreated: 43 + return "circle-dot" 44 + case NotificationTypeIssueCommented: 45 + return "message-square" 46 + case NotificationTypeIssueClosed: 47 + return "ban" 48 + case NotificationTypePullCreated: 49 + return "git-pull-request-create" 50 + case NotificationTypePullCommented: 51 + return "message-square" 52 + case NotificationTypePullMerged: 53 + return "git-merge" 54 + case NotificationTypePullClosed: 55 + return "git-pull-request-closed" 56 + case NotificationTypeFollowed: 57 + return "user-plus" 58 + default: 59 + return "" 60 + } 61 + } 62 + 63 type NotificationWithEntity struct { 64 *Notification 65 Repo *Repo
+64 -14
appview/pages/templates/notifications/fragments/item.html
··· 1 {{define "notifications/fragments/item"}} 2 - <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}}"> 3 - {{if .Issue}} 4 - {{template "issueNotification" .}} 5 - {{else if .Pull}} 6 - {{template "pullNotification" .}} 7 - {{else if .Repo}} 8 - {{template "repoNotification" .}} 9 - {{else if eq .Type "followed"}} 10 - {{template "followNotification" .}} 11 - {{else}} 12 - {{template "genericNotification" .}} 13 - {{end}} 14 - </div> 15 {{end}} 16 17 {{define "issueNotification"}} 18 {{$url := printf "/%s/%s/issues/%d" (resolve .Repo.Did) .Repo.Name .Issue.IssueId}} 19 <a ··· 37 {{ i "ban" "w-4 h-4" }} 38 </span> 39 {{end}} 40 - {{template "user/fragments/picHandle" (resolve .ActorDid)}} 41 {{if eq .Type "issue_created"}} 42 <span class="text-gray-500 dark:text-gray-400">opened issue</span> 43 {{else if eq .Type "issue_commented"}}
··· 1 {{define "notifications/fragments/item"}} 2 + <div 3 + class=" 4 + 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 5 + {{if not .Read}}bg-blue-50 dark:bg-blue-900/20 border border-blue-500 dark:border-sky-800{{end}} 6 + flex gap-2 items-center 7 + " 8 + > 9 + 10 + {{ template "notificationIcon" . }} 11 + <div class="flex-1 w-full flex flex-col gap-1"> 12 + <span>{{ template "notificationHeader" . }}</span> 13 + <span class="text-sm text-gray-500 dark:text-gray-400">{{ template "notificationSummary" . }}</span> 14 + </div> 15 + 16 + </div> 17 {{end}} 18 19 + {{ define "notificationIcon" }} 20 + <div class="flex-shrink-0 max-h-full w-16 h-16 relative"> 21 + <img class="object-cover rounded-full p-2" src="{{ fullAvatar .ActorDid }}" /> 22 + <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"> 23 + {{ i .Icon "size-3 text-black dark:text-white" }} 24 + </div> 25 + </div> 26 + {{ end }} 27 + 28 + {{ define "notificationHeader" }} 29 + {{ $actor := resolve .ActorDid }} 30 + 31 + <span class="text-black dark:text-white w-fit">{{ $actor }}</span> 32 + {{ if eq .Type "repo_starred" }} 33 + starred <span class="text-black dark:text-white">{{ resolve .Repo.Did }}/{{ .Repo.Name }}</span> 34 + {{ else if eq .Type "issue_created" }} 35 + opened an issue 36 + {{ else if eq .Type "issue_commented" }} 37 + commented on an issue 38 + {{ else if eq .Type "issue_closed" }} 39 + closed an issue 40 + {{ else if eq .Type "pull_created" }} 41 + created a pull request 42 + {{ else if eq .Type "pull_commented" }} 43 + commented on a pull request 44 + {{ else if eq .Type "pull_merged" }} 45 + merged a pull request 46 + {{ else if eq .Type "pull_closed" }} 47 + closed a pull request 48 + {{ else if eq .Type "followed" }} 49 + followed you 50 + {{ else }} 51 + {{ end }} 52 + {{ end }} 53 + 54 + {{ define "notificationSummary" }} 55 + {{ if eq .Type "repo_starred" }} 56 + <!-- no summary --> 57 + {{ else if .Issue }} 58 + #{{.Issue.IssueId}} {{.Issue.Title}} on {{resolve .Repo.Did}}/{{.Repo.Name}} 59 + {{ else if .Pull }} 60 + #{{.Pull.PullId}} {{.Pull.Title}} on {{resolve .Repo.Did}}/{{.Repo.Name}} 61 + {{ else if eq .Type "followed" }} 62 + <!-- no summary --> 63 + {{ else }} 64 + {{ end }} 65 + {{ end }} 66 + 67 {{define "issueNotification"}} 68 {{$url := printf "/%s/%s/issues/%d" (resolve .Repo.Did) .Repo.Name .Issue.IssueId}} 69 <a ··· 87 {{ i "ban" "w-4 h-4" }} 88 </span> 89 {{end}} 90 + {{template "user/fragments/picHandle" .ActorDid}} 91 {{if eq .Type "issue_created"}} 92 <span class="text-gray-500 dark:text-gray-400">opened issue</span> 93 {{else if eq .Type "issue_commented"}}
+10 -24
appview/pages/templates/notifications/list.html
··· 1 {{ define "title" }}notifications{{ end }} 2 3 {{ define "content" }} 4 - <div class="p-6"> 5 - <div class="flex items-center justify-between mb-4"> 6 <p class="text-xl font-bold dark:text-white">Notifications</p> 7 <a href="/settings/notifications" class="flex items-center gap-2"> 8 {{ i "settings" "w-4 h-4" }} ··· 11 </div> 12 </div> 13 14 - <div class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white"> 15 {{if .Notifications}} 16 - <div class="flex flex-col gap-4" id="notifications-list"> 17 {{range .Notifications}} 18 {{template "notifications/fragments/item" .}} 19 {{end}} 20 </div> 21 22 - {{if .HasMore}} 23 - <div class="mt-6 text-center"> 24 - <button 25 - class="btn gap-2 group" 26 - hx-get="/notifications?offset={{.NextOffset}}&limit={{.Limit}}" 27 - hx-target="#notifications-list" 28 - hx-swap="beforeend" 29 - > 30 - {{ i "chevron-down" "w-4 h-4 group-[.htmx-request]:hidden" }} 31 - {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 32 - Load more 33 - </button> 34 - </div> 35 - {{end}} 36 {{else}} 37 - <div class="text-center py-12"> 38 - <div class="w-16 h-16 mx-auto mb-4 text-gray-300 dark:text-gray-600"> 39 - {{ i "bell-off" "w-16 h-16" }} 40 </div> 41 - <h3 class="text-lg font-medium text-gray-900 dark:text-white mb-2">No notifications</h3> 42 - <p class="text-gray-600 dark:text-gray-400">When you receive notifications, they'll appear here.</p> 43 </div> 44 {{end}} 45 - </div> 46 {{ end }}
··· 1 {{ define "title" }}notifications{{ end }} 2 3 {{ define "content" }} 4 + <div class="px-6 py-4"> 5 + <div class="flex items-center justify-between"> 6 <p class="text-xl font-bold dark:text-white">Notifications</p> 7 <a href="/settings/notifications" class="flex items-center gap-2"> 8 {{ i "settings" "w-4 h-4" }} ··· 11 </div> 12 </div> 13 14 {{if .Notifications}} 15 + <div class="flex flex-col gap-2" id="notifications-list"> 16 {{range .Notifications}} 17 {{template "notifications/fragments/item" .}} 18 {{end}} 19 </div> 20 21 {{else}} 22 + <div class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white"> 23 + <div class="text-center py-12"> 24 + <div class="w-16 h-16 mx-auto mb-4 text-gray-300 dark:text-gray-600"> 25 + {{ i "bell-off" "w-16 h-16" }} 26 + </div> 27 + <h3 class="text-lg font-medium text-gray-900 dark:text-white mb-2">No notifications</h3> 28 + <p class="text-gray-600 dark:text-gray-400">When you receive notifications, they'll appear here.</p> 29 </div> 30 </div> 31 {{end}} 32 {{ end }}