Merge pull request #221 from nunocoracao/220-lists-should-also-have-views-and-likes

added likes and views to lists
This commit is contained in:
Nuno Coração 2022-11-09 12:05:28 +00:00 committed by GitHub
commit 30a98d5705
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 185 additions and 18 deletions

View file

@ -1499,6 +1499,14 @@ select {
margin-top: 1.25rem;
}
.mt-1 {
margin-top: 0.25rem;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.mt-12 {
margin-top: 3rem;
}
@ -1519,10 +1527,6 @@ select {
margin-top: 1.5rem;
}
.mt-1 {
margin-top: 0.25rem;
}
.mb-6 {
margin-bottom: 1.5rem;
}
@ -1567,10 +1571,6 @@ select {
margin-bottom: 2.5rem;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.-mb-1 {
margin-bottom: -0.25rem;
}
@ -2230,16 +2230,16 @@ select {
line-height: 1.75rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-base {
font-size: 1rem;
line-height: 1.5rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-xs {
font-size: 0.75rem;
line-height: 1rem;
@ -3528,16 +3528,16 @@ body:has(#menu-controller:checked) {
color: rgba(var(--color-primary-400), var(--tw-text-opacity));
}
.dark .dark\:text-neutral-300 {
--tw-text-opacity: 1;
color: rgba(var(--color-neutral-300), var(--tw-text-opacity));
}
.dark .dark\:text-neutral-400 {
--tw-text-opacity: 1;
color: rgba(var(--color-neutral-400), var(--tw-text-opacity));
}
.dark .dark\:text-neutral-300 {
--tw-text-opacity: 1;
color: rgba(var(--color-neutral-300), var(--tw-text-opacity));
}
.dark .dark\:text-neutral-800 {
--tw-text-opacity: 1;
color: rgba(var(--color-neutral-800), var(--tw-text-opacity));

View file

@ -62,8 +62,12 @@ enableCodeCopy = true
sharingLinks = [ "linkedin", "twitter", "whatsapp", "pinterest", "reddit", "facebook", "email"]
[list]
#showHero = true
#heroStyle = "background" # valid options: basic, big, background
showBreadcrumbs = false
showSummary = false
#showViews = true
#showLikes = true
showTableOfContents = false
showCards = false
groupByYear = true

View file

@ -66,6 +66,8 @@ mainSections = ["docs"]
heroStyle = "background" # valid options: basic, big, background
showBreadcrumbs = false
showSummary = false
showViews = true
showLikes = true
showTableOfContents = true
showCards = true
groupByYear = false

View file

@ -133,6 +133,8 @@ Many of the article defaults here can be overridden on a per article basis by sp
| `enableCodeCopy` | `false` | Whether copy-to-clipboard buttons are enabled for `<code>` blocks. The `highlight.noClasses` parameter must be set to `false` for code copy to function correctly. Read more about [other configuration files](#other-configuration-files) below. |
| `logo` | _Not set_ | The relative path to the site logo file within the `assets/` folder. The logo file should be provided at 2x resolution and supports any image dimensions. |
| `mainSections` | _Not set_ | The sections that should be displayed in the recent articles list. If not provided the section with the greatest number of articles is used. |
| `showViews` | _Not set_ | Whether or not articles and list views are displayed. This requires firebase integrations to be enabled, look below. |
| `showLikes` | _Not set_ | Whether or not articles and list likes are displayed. This requires firebase integrations to be enabled, look below. |
| `robots` | _Not set_ | String that indicates how robots should handle your site. If set, it will be output in the page head. Refer to [Google's docs](https://developers.google.com/search/docs/advanced/robots/robots_meta_tag#directives) for valid values. |
| `disableImageZoom` | `false` | Disables image zoom feature across all the images in the site. |
| `header.layout` | `"basic"` | Defines the header for the entire site, supported values are `basic` and `fixed`. |
@ -178,6 +180,8 @@ Many of the article defaults here can be overridden on a per article basis by sp
| `list.showBreadcrumbs` | `false` | Whether or not breadcrumbs are displayed in the header on list pages. |
| `list.showTableOfContents` | `false` | Whether or not the table of contents is displayed on list pages. |
| `list.showSummary` | `false` | Whether or not article summaries are displayed on list pages. If a summary is not provided in the [front matter]({{< ref "front-matter" >}}), one will be auto generated using the `summaryLength` parameter in the [site configuration](#site-configuration). |
| `list.showViews` | `false` | Whether or not list views are displayed. This requires firebase integrations to be enabled, look below. |
| `list.showLikes` | `false` | Whether or not list likes are displayed. This requires firebase integrations to be enabled, look below. |
| `list.showCards` | `false` | Whether or not each article is displayed as a card or as simple inline text. |
| `list.groupByYear` | `true` | Whether or not articles are grouped by year on list pages. |
| `list.cardView` | `false` | Display lists as a gallery of cards. |

View file

@ -2,6 +2,9 @@
title: "Showcase"
description: "See what's possible with Blowfish."
showLikes: true
showViews: true
cascade:
showEdit: false
showReadingTime: false

View file

@ -15,6 +15,9 @@
{{ partial "breadcrumbs.html" . }}
{{ end }}
<h1 class="mt-5 text-4xl font-extrabold text-neutral-900 dark:text-neutral">{{ .Title }}</h1>
<div class="mt-1 mb-2 text-base text-neutral-500 dark:text-neutral-400 print:hidden">
{{ partial "article-meta-list.html" (dict "context" . "scope" "single") }}
</div>
</header>
<section class="{{ if $toc -}}
mt-12
@ -31,6 +34,121 @@
<div class="min-w-0 min-h-0 max-w-prose">
{{ .Content | emojify }}
</div>
<script>
var liked_article = false
if (typeof auth !== 'undefined') {
var oid = "views_{{ .File.Path }}"
var id = oid ? oid.replaceAll("/", "-") : oid
var viewed = localStorage.getItem(id);
if (!viewed) {
auth.signInAnonymously()
.then(() => {
var docRef = db.collection('views').doc(id)
localStorage.setItem(id, true);
docRef.get().then((doc) => {
if (doc.exists) {
db.collection('views').doc(id).update({
views: firebase.firestore.FieldValue.increment(1)
});
} else {
db.collection('views').doc(id).set({ views: 1 })
}
}).catch((error) => {
console.log("Error getting document:", error);
});
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.error(errorCode, errorMessage)
});
}
var oid_likes = "likes_{{ .File.Path }}"
var id_likes = oid_likes ? oid_likes.replaceAll("/", "-") : oid_likes
var liked = localStorage.getItem(id_likes);
if (liked) {
liked_article = true
document.querySelectorAll("span[id='likes_button_heart']")[0].style.display = ""
document.querySelectorAll("span[id='likes_button_emtpty_heart']")[0].style.display = "none"
document.querySelectorAll("span[id='likes_button_text']")[0].innerText = ""
}
}
function like_article(id_likes) {
auth.signInAnonymously()
.then(() => {
var docRef = db.collection('likes').doc(id_likes)
docRef.get().then((doc) => {
liked_article = true
localStorage.setItem(id_likes, true);
document.querySelectorAll("span[id='likes_button_heart']")[0].style.display = ""
document.querySelectorAll("span[id='likes_button_emtpty_heart']")[0].style.display = "none"
document.querySelectorAll("span[id='likes_button_text']")[0].innerText = ""
if (doc.exists) {
db.collection('likes').doc(id_likes).update({
likes: firebase.firestore.FieldValue.increment(1)
});
} else {
db.collection('likes').doc(id_likes).set({ likes: 1 })
}
}).catch((error) => {
console.log("Error getting document:", error);
});
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.error(errorCode, errorMessage)
});
}
function remove_like_article(id_likes) {
auth.signInAnonymously()
.then(() => {
var docRef = db.collection('likes').doc(id_likes)
docRef.get().then((doc) => {
liked_article = false
localStorage.removeItem(id_likes);
document.querySelectorAll("span[id='likes_button_heart']")[0].style.display = "none"
document.querySelectorAll("span[id='likes_button_emtpty_heart']")[0].style.display = ""
document.querySelectorAll("span[id='likes_button_text']")[0].innerText = "\xa0Like"
if (doc.exists) {
db.collection('likes').doc(id_likes).update({
likes: firebase.firestore.FieldValue.increment(-1)
});
} else {
db.collection('likes').doc(id_likes).set({ likes: 0 })
}
}).catch((error) => {
console.log("Error getting document:", error);
});
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.error(errorCode, errorMessage)
});
}
function process_article() {
var oid_likes = "likes_{{ .File.Path }}"
var id_likes = oid_likes ? oid_likes.replaceAll("/", "-") : oid_likes
if (!liked_article) {
like_article(id_likes)
} else {
remove_like_article(id_likes)
}
}
</script>
</section>
{{ if gt .Pages 0 }}

View file

@ -0,0 +1,36 @@
{{/* Determine the correct context and scope */}}
{{/* This allows for different logic depending on where the partial is called */}}
{{ $context := . }}
{{ $scope := default nil }}
{{ if (reflect.IsMap . ) }}
{{ $context = .context }}
{{ $scope = cond (not .scope) nil .scope }}
{{ end }}
{{ with $context }}
{{ $meta := newScratch }}
{{/* Gather partials for this context */}}
{{ if (.Params.showViews | default (.Site.Params.list.showViews | default false)) }}
{{ $meta.Add "partials" (slice (partial "meta/views.html" .)) }}
{{ end }}
{{ if (.Params.showLikes | default (.Site.Params.list.showLikes | default false)) }}
{{ $meta.Add "partials" (slice (partial "meta/likes.html" .)) }}
{{ end }}
{{ if and (eq $scope "single") (.Params.showLikes | default (.Site.Params.list.showLikes | default false)) }}
{{ $meta.Add "partials" (slice (partial "meta/likes_button.html" .)) }}
{{ end }}
<div class="flex flex-row flex-wrap items-center">
{{/* Output partials */}}
{{ with ($meta.Get "partials") }}
{{ delimit . "<span class=\"px-2 text-primary-500\">&middot;</span>" }}
{{ end }}
</div>
{{ end }}