Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview/pages: rework profile overview page to use tabs model

Signed-off-by: oppiliappan <me@oppi.li>

authored by

oppiliappan and committed by
Tangled
52a70a83 53780c46

+84 -113
+14
appview/db/profile.go
··· 22 22 ByMonth []ByMonth 23 23 } 24 24 25 + func (p *ProfileTimeline) IsEmpty() bool { 26 + if p == nil { 27 + return true 28 + } 29 + 30 + for _, m := range p.ByMonth { 31 + if !m.IsEmpty() { 32 + return false 33 + } 34 + } 35 + 36 + return true 37 + } 38 + 25 39 type ByMonth struct { 26 40 RepoEvents []RepoEvent 27 41 IssueEvents IssueEvents
+4 -4
appview/db/punchcard.go
··· 29 29 Punches []Punch 30 30 } 31 31 32 - func MakePunchcard(e Execer, filters ...filter) (Punchcard, error) { 33 - punchcard := Punchcard{} 32 + func MakePunchcard(e Execer, filters ...filter) (*Punchcard, error) { 33 + punchcard := &Punchcard{} 34 34 now := time.Now() 35 35 startOfYear := time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC) 36 36 endOfYear := time.Date(now.Year(), 12, 31, 0, 0, 0, 0, time.UTC) ··· 63 63 64 64 rows, err := e.Query(query, args...) 65 65 if err != nil { 66 - return punchcard, err 66 + return nil, err 67 67 } 68 68 defer rows.Close() 69 69 ··· 72 72 var date string 73 73 var count sql.NullInt64 74 74 if err := rows.Scan(&date, &count); err != nil { 75 - return punchcard, err 75 + return nil, err 76 76 } 77 77 78 78 punch.Date, err = time.Parse(time.DateOnly, date)
+28 -9
appview/pages/pages.go
··· 409 409 return p.execute("repo/fork", w, params) 410 410 } 411 411 412 - type ProfileHomePageParams struct { 413 - LoggedInUser *oauth.User 414 - Repos []db.Repo 415 - CollaboratingRepos []db.Repo 416 - ProfileTimeline *db.ProfileTimeline 417 - Card ProfileCard 418 - Punchcard db.Punchcard 419 - } 420 - 421 412 type ProfileCard struct { 422 413 UserDid string 423 414 UserHandle string 424 415 FollowStatus db.FollowStatus 425 416 FollowersCount int 426 417 FollowingCount int 418 + Punchcard *db.Punchcard 419 + Profile *db.Profile 420 + Active string 421 + } 422 + 423 + func (p *ProfileCard) GetTabs() [][]string { 424 + tabs := [][]string{ 425 + {"overview", "overview", "square-chart-gantt"}, 426 + {"repos", "repos", "book-marked"}, 427 + {"starred", "starred", "star"}, 428 + } 429 + 430 + return tabs 431 + } 432 + 433 + type ProfileOverviewParams struct { 434 + LoggedInUser *oauth.User 435 + Repos []db.Repo 436 + CollaboratingRepos []db.Repo 437 + ProfileTimeline *db.ProfileTimeline 438 + Card *ProfileCard 439 + Active string 440 + } 441 + 442 + func (p *Pages) ProfileOverview(w io.Writer, params ProfileOverviewParams) error { 443 + params.Active = "overview" 444 + return p.executeProfile("user/overview", w, params) 445 + } 427 446 428 447 Profile *db.Profile 429 448 }
+1 -1
appview/pages/templates/user/fragments/editBio.html
··· 13 13 <label class="m-0 p-0" for="description">bio</label> 14 14 <textarea 15 15 type="text" 16 - class="py-1 px-1 w-full" 16 + class="p-2 w-full" 17 17 name="description" 18 18 rows="3" 19 19 placeholder="write a bio">{{ $description }}</textarea>
-2
appview/pages/templates/user/fragments/profileCard.html
··· 1 1 {{ define "user/fragments/profileCard" }} 2 2 {{ $userIdent := didOrHandle .UserDid .UserHandle }} 3 - <div class="bg-white dark:bg-gray-800 px-6 py-4 rounded drop-shadow-sm max-h-fit"> 4 3 <div class="grid grid-cols-3 md:grid-cols-1 gap-1 items-center"> 5 4 <div id="avatar" class="col-span-1 flex justify-center items-center"> 6 5 <div class="w-3/4 aspect-square relative"> ··· 84 85 <div id="update-profile" class="text-red-400 dark:text-red-500"></div> 85 86 </div> 86 87 </div> 87 - </div> 88 88 {{ end }} 89 89 90 90 {{ define "followerFollowing" }}
+37 -97
appview/pages/templates/user/profile.html appview/pages/templates/user/overview.html
··· 1 1 {{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }}{{ end }} 2 2 3 - {{ define "extrameta" }} 4 - <meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}" /> 5 - <meta property="og:type" content="profile" /> 6 - <meta property="og:url" content="https://tangled.sh/{{ or .Card.UserHandle .Card.UserDid }}" /> 7 - <meta property="og:description" content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" /> 8 - {{ end }} 9 - 10 - {{ define "content" }} 11 - <div class="grid grid-cols-1 md:grid-cols-11 gap-4"> 12 - <div class="md:col-span-3 order-1 md:order-1"> 13 - <div class="grid grid-cols-1 gap-4"> 14 - {{ template "user/fragments/profileCard" .Card }} 15 - {{ block "punchcard" .Punchcard }} {{ end }} 16 - </div> 3 + {{ define "profileContent" }} 4 + <div id="all-repos" class="md:col-span-4 order-2 md:order-2"> 5 + <div class="grid grid-cols-1 gap-4"> 6 + {{ block "ownRepos" . }}{{ end }} 7 + {{ block "collaboratingRepos" . }}{{ end }} 17 8 </div> 18 - <div id="all-repos" class="md:col-span-4 order-2 md:order-2"> 19 - <div class="grid grid-cols-1 gap-4"> 20 - {{ block "ownRepos" . }}{{ end }} 21 - {{ block "collaboratingRepos" . }}{{ end }} 22 - </div> 23 - </div> 24 - <div class="md:col-span-4 order-3 md:order-3"> 25 - {{ block "profileTimeline" . }}{{ end }} 26 - </div> 27 - </div> 9 + </div> 10 + <div class="md:col-span-4 order-3 md:order-3"> 11 + {{ block "profileTimeline" . }}{{ end }} 12 + </div> 28 13 {{ end }} 29 14 30 15 {{ define "profileTimeline" }} 31 - <p class="text-sm font-bold p-2 dark:text-white">ACTIVITY</p> 16 + <p class="text-sm font-bold px-2 pb-4 dark:text-white">ACTIVITY</p> 32 17 <div class="flex flex-col gap-4 relative"> 18 + {{ if .ProfileTimeline.IsEmpty }} 19 + <p class="dark:text-white">This user does not have any activity yet.</p> 20 + {{ end }} 21 + 33 22 {{ with .ProfileTimeline }} 34 23 {{ range $idx, $byMonth := .ByMonth }} 35 24 {{ with $byMonth }} 36 - <div class="bg-white dark:bg-gray-800 px-6 py-4 rounded drop-shadow-sm"> 37 - {{ if eq $idx 0 }} 25 + {{ if not .IsEmpty }} 26 + <div class="border border-gray-200 dark:border-gray-700 rounded-sm py-4 px-6"> 27 + <p class="text-sm font-mono mb-2 text-gray-500 dark:text-gray-400"> 28 + {{ if eq $idx 0 }} 29 + this month 30 + {{ else }} 31 + {{$idx}} month{{if ne $idx 1}}s{{end}} ago 32 + {{ end }} 33 + </p> 38 34 39 - {{ else }} 40 - {{ $s := "s" }} 41 - {{ if eq $idx 1 }} 42 - {{ $s = "" }} 43 - {{ end }} 44 - <p class="text-sm font-bold dark:text-white mb-2">{{$idx}} month{{$s}} ago</p> 45 - {{ end }} 46 - 47 - {{ if .IsEmpty }} 48 - <div class="text-gray-500 dark:text-gray-400"> 49 - No activity for this month 50 - </div> 51 - {{ else }} 52 - <div class="flex flex-col gap-1"> 53 - {{ block "repoEvents" .RepoEvents }} {{ end }} 54 - {{ block "issueEvents" .IssueEvents }} {{ end }} 55 - {{ block "pullEvents" .PullEvents }} {{ end }} 35 + <div class="flex flex-col gap-1"> 36 + {{ block "repoEvents" .RepoEvents }} {{ end }} 37 + {{ block "issueEvents" .IssueEvents }} {{ end }} 38 + {{ block "pullEvents" .PullEvents }} {{ end }} 39 + </div> 56 40 </div> 57 41 {{ end }} 58 - </div> 59 - 60 42 {{ end }} 61 - {{ else }} 62 - <p class="dark:text-white">This user does not have any activity yet.</p> 63 43 {{ end }} 64 44 {{ end }} 65 45 </div> ··· 212 232 213 233 {{ define "ownRepos" }} 214 234 <div> 215 - <div class="text-sm font-bold p-2 pr-0 dark:text-white flex items-center justify-between gap-2"> 235 + <div class="text-sm font-bold px-2 pb-4 dark:text-white flex items-center gap-2"> 216 236 <a href="/@{{ or $.Card.UserHandle $.Card.UserDid }}?tab=repos" 217 237 class="flex text-black dark:text-white items-center gap-2 no-underline hover:no-underline group"> 218 238 <span>PINNED REPOS</span> 219 - <span class="flex gap-1 items-center font-normal text-sm text-gray-500 dark:text-gray-400 "> 220 - view all {{ i "chevron-right" "w-4 h-4" }} 221 - </span> 222 239 </a> 223 240 {{ if and .LoggedInUser (eq .LoggedInUser.Did .Card.UserDid) }} 224 - <button 241 + <button 225 242 hx-get="profile/edit-pins" 226 243 hx-target="#all-repos" 227 - class="btn py-0 font-normal text-sm flex gap-2 items-center group"> 244 + class="py-0 font-normal text-sm flex gap-2 items-center group"> 228 245 {{ i "pencil" "w-3 h-3" }} 229 - edit 230 246 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 231 247 </button> 232 248 {{ end }} 233 249 </div> 234 250 <div id="repos" class="grid grid-cols-1 gap-4 items-stretch"> 235 251 {{ range .Repos }} 252 + <div class="border border-gray-200 dark:border-gray-700 rounded-sm"> 236 253 {{ template "user/fragments/repoCard" (list $ . false) }} 254 + </div> 237 255 {{ else }} 238 - <p class="px-6 dark:text-white">This user does not have any repos yet.</p> 256 + <p class="dark:text-white">This user does not have any pinned repos.</p> 239 257 {{ end }} 240 258 </div> 241 259 </div> ··· 242 264 {{ define "collaboratingRepos" }} 243 265 {{ if gt (len .CollaboratingRepos) 0 }} 244 266 <div> 245 - <p class="text-sm font-bold p-2 dark:text-white">COLLABORATING ON</p> 267 + <p class="text-sm font-bold px-2 pb-4 dark:text-white">COLLABORATING ON</p> 246 268 <div id="collaborating" class="grid grid-cols-1 gap-4"> 247 269 {{ range .CollaboratingRepos }} 270 + <div class="border border-gray-200 dark:border-gray-700 rounded-sm"> 248 271 {{ template "user/fragments/repoCard" (list $ . true) }} 272 + </div> 249 273 {{ else }} 250 274 <p class="px-6 dark:text-white">This user is not collaborating.</p> 251 275 {{ end }} ··· 256 276 {{ end }} 257 277 {{ end }} 258 278 259 - {{ define "punchcard" }} 260 - {{ $now := now }} 261 - <div> 262 - <p class="p-2 flex gap-2 text-sm font-bold dark:text-white"> 263 - PUNCHCARD 264 - <span class="font-normal text-sm text-gray-500 dark:text-gray-400 "> 265 - {{ .Total | int64 | commaFmt }} commits 266 - </span> 267 - </p> 268 - <div class="bg-white dark:bg-gray-800 px-6 py-4 rounded drop-shadow-sm"> 269 - <div class="grid grid-cols-28 md:grid-cols-14 gap-y-2 w-full h-full"> 270 - {{ range .Punches }} 271 - {{ $count := .Count }} 272 - {{ $theme := "bg-gray-200 dark:bg-gray-700 size-[4px]" }} 273 - {{ if lt $count 1 }} 274 - {{ $theme = "bg-gray-200 dark:bg-gray-700 size-[4px]" }} 275 - {{ else if lt $count 2 }} 276 - {{ $theme = "bg-green-200 dark:bg-green-900 size-[5px]" }} 277 - {{ else if lt $count 4 }} 278 - {{ $theme = "bg-green-300 dark:bg-green-800 size-[5px]" }} 279 - {{ else if lt $count 8 }} 280 - {{ $theme = "bg-green-400 dark:bg-green-700 size-[6px]" }} 281 - {{ else }} 282 - {{ $theme = "bg-green-500 dark:bg-green-600 size-[7px]" }} 283 - {{ end }} 284 - 285 - {{ if .Date.After $now }} 286 - {{ $theme = "border border-gray-200 dark:border-gray-700 size-[4px]" }} 287 - {{ end }} 288 - <div class="w-full h-full flex justify-center items-center"> 289 - <div 290 - class="aspect-square rounded-full transition-all duration-300 {{ $theme }} max-w-full max-h-full" 291 - title="{{ .Date.Format "2006-01-02" }}: {{ .Count }} commits"> 292 - </div> 293 - </div> 294 - {{ end }} 295 - </div> 296 - </div> 297 - </div> 298 - {{ end }}