diff options
author | silverwind <me@silverwind.io> | 2020-11-18 23:00:16 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-18 16:00:16 -0600 |
commit | 12c2efb45c112baf6013c304c35cbd404f7be21a (patch) | |
tree | 2deb1fd0a4c09b048c9e4f262057bfe4cfa774b1 | |
parent | d02c3508e629d854d0094f4562c4cdebfada5962 (diff) | |
download | gitea-12c2efb45c112baf6013c304c35cbd404f7be21a.tar.gz gitea-12c2efb45c112baf6013c304c35cbd404f7be21a.zip |
Remove fetch request from heatmap (#13623)
* Remove fetch request from heatmap
Render heatmap data directly to HTML, eliminating one HTTP request on
frontpage and user profile. Also added min-height to the container so
the page content will no longer move after loading.
* rename and error display
* also log the js error
* add error handler
* remove useless inline style and hide divider on small screens
* Update routers/user/home.go
* Update routers/user/profile.go
-rw-r--r-- | routers/user/home.go | 10 | ||||
-rw-r--r-- | routers/user/profile.go | 12 | ||||
-rw-r--r-- | templates/base/head.tmpl | 2 | ||||
-rw-r--r-- | templates/user/dashboard/dashboard.tmpl | 5 | ||||
-rw-r--r-- | templates/user/heatmap.tmpl (renamed from templates/user/dashboard/heatmap.tmpl) | 9 | ||||
-rw-r--r-- | templates/user/profile.tmpl | 5 | ||||
-rw-r--r-- | web_src/js/components/ActivityHeatmap.vue | 25 | ||||
-rw-r--r-- | web_src/js/features/heatmap.js | 23 | ||||
-rw-r--r-- | web_src/js/features/userheatmap.js | 10 | ||||
-rw-r--r-- | web_src/js/index.js | 4 | ||||
-rw-r--r-- | web_src/less/features/heatmap.less | 55 |
11 files changed, 86 insertions, 74 deletions
diff --git a/routers/user/home.go b/routers/user/home.go index f7f1786b33..779971ca97 100644 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -114,8 +114,14 @@ func Dashboard(ctx *context.Context) { ctx.Data["SearchLimit"] = setting.UI.User.RepoPagingNum // no heatmap access for admins; GetUserHeatmapDataByUser ignores the calling user // so everyone would get the same empty heatmap - ctx.Data["EnableHeatmap"] = setting.Service.EnableUserHeatmap && !ctxUser.KeepActivityPrivate - ctx.Data["HeatmapUser"] = ctxUser.Name + if setting.Service.EnableUserHeatmap && !ctxUser.KeepActivityPrivate { + data, err := models.GetUserHeatmapDataByUser(ctxUser) + if err != nil { + ctx.ServerError("GetUserHeatmapDataByUser", err) + return + } + ctx.Data["HeatmapData"] = data + } var err error var mirrors []*models.Repository diff --git a/routers/user/profile.go b/routers/user/profile.go index 8bf5cacc56..36f3d0735d 100644 --- a/routers/user/profile.go +++ b/routers/user/profile.go @@ -94,10 +94,18 @@ func Profile(ctx *context.Context) { ctx.Data["PageIsUserProfile"] = true ctx.Data["Owner"] = ctxUser ctx.Data["OpenIDs"] = openIDs + // no heatmap access for admins; GetUserHeatmapDataByUser ignores the calling user // so everyone would get the same empty heatmap - ctx.Data["EnableHeatmap"] = setting.Service.EnableUserHeatmap && !ctxUser.KeepActivityPrivate - ctx.Data["HeatmapUser"] = ctxUser.Name + if setting.Service.EnableUserHeatmap && !ctxUser.KeepActivityPrivate { + data, err := models.GetUserHeatmapDataByUser(ctxUser) + if err != nil { + ctx.ServerError("GetUserHeatmapDataByUser", err) + return + } + ctx.Data["HeatmapData"] = data + } + if len(ctxUser.Description) != 0 { ctx.Data["RenderedDescription"] = string(markdown.Render([]byte(ctxUser.Description), ctx.Repo.RepoLink, map[string]string{"mode": "document"})) } diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index 4738b91463..c8e669387b 100644 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -36,8 +36,6 @@ SimpleMDE: {{if .RequireSimpleMDE}}true{{else}}false{{end}}, Tribute: {{if .RequireTribute}}true{{else}}false{{end}}, U2F: {{if .RequireU2F}}true{{else}}false{{end}}, - Heatmap: {{if .EnableHeatmap}}true{{else}}false{{end}}, - heatmapUser: {{if .HeatmapUser}}'{{.HeatmapUser}}'{{else}}null{{end}}, NotificationSettings: { MinTimeout: {{NotificationSettings.MinTimeout}}, TimeoutStep: {{NotificationSettings.TimeoutStep}}, diff --git a/templates/user/dashboard/dashboard.tmpl b/templates/user/dashboard/dashboard.tmpl index 7a4968ebe6..dc04d65651 100644 --- a/templates/user/dashboard/dashboard.tmpl +++ b/templates/user/dashboard/dashboard.tmpl @@ -5,10 +5,7 @@ {{template "base/alert" .}} <div class="ui mobile reversed stackable grid"> <div class="ui container ten wide column"> - {{if .EnableHeatmap}} - {{template "user/dashboard/heatmap" .}} - <div class="ui divider"></div> - {{end}} + {{template "user/heatmap" .}} {{template "user/dashboard/feeds" .}} </div> {{template "user/dashboard/repolist" .}} diff --git a/templates/user/dashboard/heatmap.tmpl b/templates/user/heatmap.tmpl index 626c70dd8d..a569405d16 100644 --- a/templates/user/dashboard/heatmap.tmpl +++ b/templates/user/heatmap.tmpl @@ -1,7 +1,8 @@ -<div id="user-heatmap" style="padding-right: 40px"> - <activity-heatmap :locale="locale" :suburl="suburl" :user="heatmapUser"> +{{if .HeatmapData}} + <div id="user-heatmap" data-heatmap-data="{{Json .HeatmapData}}"> <div slot="loading"> <div class="ui active centered inline indeterminate text loader" id="loading-heatmap">{{.i18n.Tr "user.heatmap.loading"}}</div> </div> - </activity-heatmap> -</div> + </div> + <div class="ui divider"></div> +{{end}} diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl index 3a3192a828..d6b99b3861 100644 --- a/templates/user/profile.tmpl +++ b/templates/user/profile.tmpl @@ -108,10 +108,7 @@ <p>{{.i18n.Tr "user.disabled_public_activity"}}</p> </div> {{end}} - {{if .EnableHeatmap}} - {{template "user/dashboard/heatmap" .}} - <div class="ui divider"></div> - {{end}} + {{template "user/heatmap" .}} <div class="feeds"> {{template "user/dashboard/feeds" .}} </div> diff --git a/web_src/js/components/ActivityHeatmap.vue b/web_src/js/components/ActivityHeatmap.vue index 1970cb609a..943bf704e2 100644 --- a/web_src/js/components/ActivityHeatmap.vue +++ b/web_src/js/components/ActivityHeatmap.vue @@ -1,13 +1,9 @@ <template> - <div class="heatmap-container"> - <div v-show="isLoading"> - <slot name="loading"/> - </div> - <div v-if="!isLoading" class="total-contributions"> + <div id="user-heatmap"> + <div class="total-contributions"> {{ values.length }} contributions in the last 12 months </div> <calendar-heatmap - v-show="!isLoading" :locale="locale" :no-data-text="locale.no_contributions" :tooltip-unit="locale.contributions" @@ -19,13 +15,17 @@ </template> <script> import {CalendarHeatmap} from 'vue-calendar-heatmap'; -const {AppSubUrl, heatmapUser} = window.config; export default { name: 'ActivityHeatmap', components: {CalendarHeatmap}, + props: { + values: { + type: Array, + default: () => [], + }, + }, data: () => ({ - isLoading: true, colorRange: [ 'var(--color-secondary-alpha-70)', 'var(--color-primary-light-4)', @@ -35,20 +35,11 @@ export default { 'var(--color-primary-dark-4)', ], endDate: new Date(), - values: [], locale: { contributions: 'contributions', no_contributions: 'No contributions', }, }), - async mounted() { - const res = await fetch(`${AppSubUrl}/api/v1/users/${heatmapUser}/heatmap`); - const data = await res.json(); - this.values = data.map(({contributions, timestamp}) => { - return {date: new Date(timestamp * 1000), count: contributions}; - }); - this.isLoading = false; - }, }; </script> <style scoped/> diff --git a/web_src/js/features/heatmap.js b/web_src/js/features/heatmap.js new file mode 100644 index 0000000000..d1cb43dde0 --- /dev/null +++ b/web_src/js/features/heatmap.js @@ -0,0 +1,23 @@ +import Vue from 'vue'; + +import ActivityHeatmap from '../components/ActivityHeatmap.vue'; + +export default async function initHeatmap() { + const el = document.getElementById('user-heatmap'); + if (!el) return; + + try { + const values = JSON.parse(el.dataset.heatmapData).map(({contributions, timestamp}) => { + return {date: new Date(timestamp * 1000), count: contributions}; + }); + + const View = Vue.extend({ + render: (createElement) => createElement(ActivityHeatmap, {props: {values}}), + }); + + new View().$mount(el); + } catch (err) { + console.error(err); + el.textContent = 'Heatmap failed to load'; + } +} diff --git a/web_src/js/features/userheatmap.js b/web_src/js/features/userheatmap.js deleted file mode 100644 index f7e0d1a75f..0000000000 --- a/web_src/js/features/userheatmap.js +++ /dev/null @@ -1,10 +0,0 @@ -import Vue from 'vue'; - -import ActivityHeatmap from '../components/ActivityHeatmap.vue'; - -export default async function initUserHeatmap() { - const el = document.getElementById('user-heatmap'); - if (!el) return; - const View = Vue.extend(ActivityHeatmap); - new View().$mount(el); -} diff --git a/web_src/js/index.js b/web_src/js/index.js index 1f4c9a509a..fc49195607 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -12,7 +12,7 @@ import initMigration from './features/migration.js'; import initContextPopups from './features/contextpopup.js'; import initGitGraph from './features/gitgraph.js'; import initClipboard from './features/clipboard.js'; -import initUserHeatmap from './features/userheatmap.js'; +import initHeatmap from './features/heatmap.js'; import initProject from './features/projects.js'; import initServiceWorker from './features/serviceworker.js'; import initMarkdownAnchors from './markdown/anchors.js'; @@ -2553,7 +2553,7 @@ $(document).ready(async () => { attachTribute(document.querySelectorAll('#content, .emoji-input')), initGitGraph(), initClipboard(), - initUserHeatmap(), + initHeatmap(), initProject(), initServiceWorker(), initNotificationCount(), diff --git a/web_src/less/features/heatmap.less b/web_src/less/features/heatmap.less index 5383847387..61db5c81b0 100644 --- a/web_src/less/features/heatmap.less +++ b/web_src/less/features/heatmap.less @@ -1,49 +1,50 @@ #user-heatmap { - width: 107%; // Fixes newest contributions not showing + width: 100%; text-align: center; + position: relative; + min-height: 125px; + display: flex; + align-items: center; + justify-content: center; svg:not(:root) { overflow: inherit; padding: 0 !important; } + text { + fill: currentColor !important; + } + @media @mediaLgAndDown { - & { + &, + & + .divider { display: none; } } .total-contributions { - text-align: left; - margin-top: 0; + font-size: 11px; + position: absolute; + bottom: 0; + left: 25px; } -} - -.heatmap-container { - position: relative; -} -.heatmap-container .total-contributions { - font-size: 11px; - position: absolute; - bottom: 0; - left: 25px; -} - -@media @mediaLgAndDown { - .heatmap-container .total-contributions { - left: 21px; + @media @mediaLgAndDown { + .total-contributions { + left: 21px; + } } -} -@media (max-width: 1000px) { - .heatmap-container .total-contributions { - font-size: 10px; - left: 17px; - bottom: -2px; + @media (max-width: 1000px) { + .total-contributions { + font-size: 10px; + left: 17px; + bottom: -2px; + } } } -.heatmap-container text { - fill: currentColor !important; +.user.profile #user-heatmap { + min-height: 135px; } |