Merge branch 'main' of github.com:maiani/toha

This commit is contained in:
Andrea Maiani 2024-12-09 10:49:31 +01:00
commit 82b08ccd5e
53 changed files with 3093 additions and 1069 deletions

View file

@ -0,0 +1,9 @@
let theme = localStorage.getItem('theme-scheme') || localStorage.getItem('darkmode:color-scheme') || 'light'
if (theme === 'system') {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
theme = 'dark'
} else {
theme = 'light'
}
}
document.documentElement.setAttribute('data-theme', theme)

View file

@ -0,0 +1,22 @@
addCopyButtons(navigator.clipboard)
function addCopyButtons(clipboard) {
document.querySelectorAll('pre > code').forEach(function (codeBlock) {
const button = document.createElement('button')
button.title = "Copy"
button.className = 'copy-code-button btn btn-sm'
button.innerHTML = "<i class='fa-regular fa-copy'></i>"
button.addEventListener('click', function () {
clipboard.writeText(codeBlock.innerText)
})
const pre = codeBlock.parentNode
if (pre.parentNode.classList.contains('highlight')) {
const highlight = pre.parentNode
highlight.parentNode.insertBefore(button, highlight)
} else {
pre.parentNode.insertBefore(button, pre)
}
})
}

View file

@ -0,0 +1 @@
import './copyCode'

View file

@ -10,6 +10,10 @@ if (process.env.FEATURE_DARKMODE === '1') {
import('./darkmode')
}
if (process.env.FEATURE_THEME === '1') {
import('./theme')
}
if (process.env.FEATURE_FLOWCHART === '1') {
import('./flowchart')
}
@ -25,3 +29,7 @@ if (process.env.FEATURE_MATH === '1') {
if (process.env.FEATURE_EMBEDPDF === '1') {
import('./embedpdf')
}
if (process.env.FEATURE_COPYCODEBUTTON === '1') {
import('./copyCode')
}

View file

@ -0,0 +1,88 @@
import * as params from '@params';
const PERSISTENCE_KEY = 'theme-scheme'
const themeOptions = params.theme || {}
const THEME_DARK = typeof themeOptions.dark === 'undefined' ? true : themeOptions.dark;
const THEME_LIGHT = typeof themeOptions.light === 'undefined' ? true : themeOptions.light;
const THEME_DEFAULT = typeof themeOptions.default === 'undefined' ? "system" : themeOptions.default;
window.addEventListener('load', async () => {
const menu = document.getElementById('themeMenu')
const $icon = document.getElementById('navbar-theme-icon-svg')
if (menu == null || $icon == null) return
const btns = menu.getElementsByTagName('a')
const iconMap = Array.from(btns).reduce((map, btn) => {
const $img = btn.getElementsByTagName('img')[0]
map[btn.dataset.scheme] = $img.src
return map
}, {})
function checkScheme(scheme) {
if (THEME_LIGHT === false) return "dark"
if (THEME_DARK === false) return "light"
return scheme
}
function loadScheme() {
return localStorage.getItem(PERSISTENCE_KEY) || loadDefaultScheme()
}
function loadDefaultScheme() {
return THEME_DEFAULT || "system"
}
function saveScheme(scheme) {
localStorage.setItem(PERSISTENCE_KEY, scheme)
}
function getPreferredColorScheme() {
const isDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
return isDarkMode ? "dark" : "light";
}
function setScheme(newScheme) {
let theme = newScheme
if (newScheme === 'system') {
theme = getPreferredColorScheme()
}
// set data-theme attribute on html tag
document.querySelector("html").dataset.theme = theme;
// update icon
$icon.src = iconMap[newScheme]
// save preference to local storage
saveScheme(newScheme)
setImages(theme)
}
const checkedScheme = checkScheme(loadScheme())
setScheme(checkedScheme)
Array.from(menu.getElementsByTagName('a')).forEach((btn) => {
btn.addEventListener('click', () => {
const { scheme } = btn.dataset
setScheme(scheme)
})
})
})
function setImages(newScheme) {
const els = Array.from(document.getElementsByClassName('logo-holder'));
for (const el of els) {
const light = el.querySelector('.light-logo');
const dark = el.querySelector('.dark-logo');
if (newScheme === "dark" && dark !== null) {
if (light !== null) light.style.display = 'none'
dark.style.display = 'inline'
}
else {
if (light !== null) light.style.display = 'inline'
if (dark !== null) dark.style.display = 'none'
}
}
}

View file

@ -7,7 +7,7 @@ window.addEventListener('DOMContentLoaded', () => {
const fuseOptions = {
shouldSort: true,
includeMatches: true,
threshold: 0.0,
threshold: 0.1,
tokenize: true,
location: 0,
distance: 100,

View file

@ -4,4 +4,5 @@ import './sidebar'
import './education'
import './achievements'
import './projects'
import './skills'
import './publications'

View file

@ -0,0 +1,15 @@
import Filterizr from 'filterizr'
document.addEventListener('DOMContentLoaded', () => {
// ================== Skill cards =====================
// setup skill filter buttons
const skillCardHolder = document.getElementById('skill-card-holder')
if (skillCardHolder != null && skillCardHolder.children.length !== 0) {
// eslint-disable-next-line no-new
new Filterizr('.filtr-skills', {
layout: 'sameWidth',
controlsSelector: '.skill-filtr-control'
})
}
})

View file

@ -102,6 +102,40 @@
}
}
.copy-code-button {
float: right;
margin-top: 0.5em;
margin-left: -2.6em;
margin-right: 3em;
background-color: get-light-color('text-color') !important;
color: get-light-color('inverse-text-color') !important;
padding: 0.25rem 0.5rem;
line-height: 1.5;
border-radius: 0.2rem;
border: none;
&:hover,
&:focus {
background-color: get-light-color('accent-color') !important;
color: get-light-color('text-over-accent-color') !important;
@include transition();
}
&:focus {
&::before {
content: 'Copied!';
position: absolute;
padding: 0.3em;
border-radius: 0.2em;
margin-left: -5em;
margin-top: -0.2em;
background-color: get-light-color('accent-color') !important;
color: get-light-color('text-over-accent-color') !important;
@include transition();
}
}
}
html[data-theme='dark'] {
.btn-dark {
background-color: get-dark-color('accent-color') !important;
@ -169,4 +203,15 @@ html[data-theme='dark'] {
background-color: get-dark-color('hover-over-accent-color') !important;
}
}
.copy-code-button {
background-color: get-dark-color('bg-primary') !important;
color: get-dark-color('muted-text-color') !important;
&:hover,
&:focus,
&::before {
background-color: get-dark-color('accent-color') !important;
color: get-dark-color('text-over-accent-color') !important;
}
}
}

View file

@ -9,6 +9,11 @@
box-shadow: $box-shadow;
border: 1px solid get-light-color('bg-primary');
@include transition();
.card-img-top {
transform: scale(1.2);
object-fit: cover;
@include transition();
}
}
.card-head {
@ -17,12 +22,17 @@
overflow: hidden;
}
.card-title {
font-size: large;
}
.card-body {
text-align: justify;
text-align: left;
}
.card-img-top {
object-fit: cover;
-o-object-fit: cover;
object-fit: cover;
@include transition();
}
@ -61,7 +71,8 @@
&:focus {
.card-img-top {
transform: scale(1.2);
object-fit: cover;
-o-object-fit: cover;
object-fit: cover;
@include transition();
}
}

View file

@ -8,7 +8,8 @@ a {
&:hover,
&:focus {
text-decoration: get-light-color('hover-over-accent-color') underline;
-webkit-text-decoration: get-light-color('hover-over-accent-color') underline;
text-decoration: get-light-color('hover-over-accent-color') underline;
color: get-light-color('hover-over-accent-color');
@include transition();
}
@ -66,7 +67,8 @@ html[data-theme='dark'] {
&:hover,
&:focus {
text-decoration: get-dark-color('hover-over-accent-color') underline;
-webkit-text-decoration: get-dark-color('hover-over-accent-color') underline;
text-decoration: get-dark-color('hover-over-accent-color') underline;
color: get-dark-color('hover-over-accent-color');
}
}

View file

@ -96,6 +96,10 @@ html[data-theme='dark'] {
}
}
.gist {
&::-moz-selection{
background: get-dark-color('text-color');
color: get-dark-color('inverse-text-color');
}
&::selection{
background: get-dark-color('text-color');
color: get-dark-color('inverse-text-color');

View file

@ -12,7 +12,7 @@ strong {
p {
color: get-light-color('text-color');
text-align: justify;
text-align: left;
text-justify: inter-word;
}

View file

@ -1,6 +1,6 @@
// in Hugo, Page kind can be either "section" or "page".
// if it is section, then it's a page with a list of items, for example /posts
// if it is page, then it is a single page.
/* in Hugo, Page kind can be either "section" or "page".*/
/* if it is section, then it's a page with a list of items, for example /posts*/
/* if it is page, then it is a single page.*/
body.kind-section,
body.kind-term,
body.kind-page {

View file

@ -53,7 +53,6 @@ body {
ol > ol,
li > ol,
li > ul {
-webkit-padding-start: 1rem;
padding-inline-start: 1rem;
}
}

View file

@ -13,7 +13,8 @@
@include transition();
&:hover {
margin-left: 5px;
text-decoration: get-light-color('muted-text-color') underline;
-webkit-text-decoration: get-light-color('muted-text-color') underline;
text-decoration: get-light-color('muted-text-color') underline;
@include transition();
}
}
@ -79,7 +80,8 @@ html[data-theme='dark'] {
a {
color: get-dark-color('muted-text-color');
&:hover {
text-decoration: get-dark-color('muted-text-color') underline;
-webkit-text-decoration: get-dark-color('muted-text-color') underline;
text-decoration: get-dark-color('muted-text-color') underline;
}
}
@ -95,6 +97,10 @@ html[data-theme='dark'] {
background-color: get-dark-color('bg-primary');
&:focus {
background-color: get-dark-color('bg-secondary');
color: get-dark-color('text-color');
}
&::placeholder {
color: get-dark-color('muted-text-color');
}
}

View file

@ -42,7 +42,4 @@
@keyframes spin {
to { -webkit-transform: rotate(360deg); }
}
@-webkit-keyframes spin {
to { -webkit-transform: rotate(360deg); }
}
}