feat: add "other" button with dynamic link list for additional projects and services
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -39,6 +39,25 @@ class Global_conf {
|
|||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// List shown under the "other" button on the home page.
|
||||||
|
// section => array( array(label, url, note), ... )
|
||||||
|
// Relative URLs open in the same tab, absolute (https://...) in a new tab.
|
||||||
|
public $other_links = array(
|
||||||
|
"projects" => array(
|
||||||
|
array("Ločenice – Sluneční vrch", "/locenice/", ""),
|
||||||
|
array("Klabava – rodinný dům", "/klabava/", ""),
|
||||||
|
array("Kovářova – rodinný dům", "/kovarova/", ""),
|
||||||
|
),
|
||||||
|
"services" => array(
|
||||||
|
array("Valheim map", "https://valheim-mapa.martinfencl.eu/", ""),
|
||||||
|
array("Dashboard", "https://dashboard.martinfencl.eu/", "Homarr"),
|
||||||
|
array("Photos", "https://photo.martinfencl.eu/", "Immich"),
|
||||||
|
array("Cloud", "https://cloud.martinfencl.eu/", "Nextcloud"),
|
||||||
|
array("Film", "https://film.martinfencl.eu/", "Jellyfin"),
|
||||||
|
array("BetterShift", "https://bettershift.martinfencl.eu/", "shifts"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|||||||
+100
@@ -716,3 +716,103 @@ button:hover {
|
|||||||
button:focus {
|
button:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* "other" – half-size twin of the "about me" button, opens a link list above itself */
|
||||||
|
#Other_wrap {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Other_btn {
|
||||||
|
width: 90px;
|
||||||
|
height: 20px;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 1;
|
||||||
|
border-width: 1px;
|
||||||
|
box-shadow: 2px 2px 0 #6f619e,
|
||||||
|
-2px -2px 0 #6f619e,
|
||||||
|
-2px 2px 0 #6f619e,
|
||||||
|
2px -2px 0 #6f619e;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Other_btn:hover,
|
||||||
|
#Other_btn[aria-expanded="true"] {
|
||||||
|
box-shadow: 10px 2px 0 #6f619e, -10px -2px 0 #6f619e;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Other_list {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
bottom: calc(100% + 10px); /* low enough to fully cover the "about me" button while open */
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
z-index: 5;
|
||||||
|
width: 300px;
|
||||||
|
max-width: calc(100vw - 32px);
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 15px 20px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.95);
|
||||||
|
-webkit-backdrop-filter: blur(6px);
|
||||||
|
backdrop-filter: blur(6px);
|
||||||
|
border-radius: 15px;
|
||||||
|
color: rgb(238, 238, 255);
|
||||||
|
text-align: left;
|
||||||
|
font-family: Lucida Console, Lucida Sans Typewriter, monaco, Bitstream Vera Sans Mono, monospace;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Other_list .other-section {
|
||||||
|
margin-top: 12px;
|
||||||
|
font-size: 11px;
|
||||||
|
letter-spacing: .15em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #a99fd0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Other_list .other-section:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Other_list ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Other_list a {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 10px;
|
||||||
|
margin: 0 -8px;
|
||||||
|
padding: 1px 8px;
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Other_list a:hover,
|
||||||
|
#Other_list a:focus-visible {
|
||||||
|
background-color: rgba(111, 97, 158, 0.55);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Other_list .other-note {
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgba(238, 238, 255, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
#Other_list_arrow {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: -7px;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
margin-left: -8px;
|
||||||
|
border-left: 8px solid transparent;
|
||||||
|
border-right: 8px solid transparent;
|
||||||
|
border-top: 7px solid rgba(0, 0, 0, 0.95);
|
||||||
|
}
|
||||||
|
|||||||
@@ -104,6 +104,27 @@
|
|||||||
<button class="name noselect">about me</button>
|
<button class="name noselect">about me</button>
|
||||||
</form>
|
</form>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div id="Other_wrap">
|
||||||
|
<button type="button" id="Other_btn" class="noselect" aria-expanded="false" aria-controls="Other_list">other</button>
|
||||||
|
<div id="Other_list">
|
||||||
|
<?php foreach ($global->other_links as $section => $links): ?>
|
||||||
|
<div class="other-section"><?php echo htmlspecialchars($section); ?></div>
|
||||||
|
<ul>
|
||||||
|
<?php foreach ($links as $link):
|
||||||
|
$is_external = strpos($link[1], 'http') === 0; ?>
|
||||||
|
<li><a href="<?php echo htmlspecialchars($link[1]); ?>"<?php if ($is_external) echo ' target="_blank" rel="noopener"'; ?>>
|
||||||
|
<span><?php echo htmlspecialchars($link[0]); ?></span>
|
||||||
|
<?php if ($link[2] !== ''): ?>
|
||||||
|
<span class="other-note"><?php echo htmlspecialchars($link[2]); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</a></li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<div id="Other_list_arrow"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -136,6 +157,32 @@
|
|||||||
$("#Bank_info_ext").stop().fadeOut(300);
|
$("#Bank_info_ext").stop().fadeOut(300);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var $otherBtn = $("#Other_btn");
|
||||||
|
var $otherList = $("#Other_list");
|
||||||
|
|
||||||
|
function setOtherOpen(open) {
|
||||||
|
if (open === ($otherBtn.attr("aria-expanded") === "true")) return;
|
||||||
|
$otherBtn.attr("aria-expanded", open ? "true" : "false");
|
||||||
|
if (open) {
|
||||||
|
$otherList.stop(true, true).fadeIn(200);
|
||||||
|
} else {
|
||||||
|
$otherList.stop(true, true).fadeOut(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$otherBtn.on("click", function () {
|
||||||
|
setOtherOpen($otherBtn.attr("aria-expanded") !== "true");
|
||||||
|
});
|
||||||
|
|
||||||
|
// close on click outside or Escape
|
||||||
|
$(document).on("click", function (e) {
|
||||||
|
if (!$(e.target).closest("#Other_wrap").length) setOtherOpen(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on("keydown", function (e) {
|
||||||
|
if (e.key === "Escape" || e.keyCode === 27) setOtherOpen(false);
|
||||||
|
});
|
||||||
|
|
||||||
function copyNumber() {
|
function copyNumber() {
|
||||||
copyToClipboard('<?php echo $global->phone_list[0]; ?>');
|
copyToClipboard('<?php echo $global->phone_list[0]; ?>');
|
||||||
alert("phone copied to clipboard")
|
alert("phone copied to clipboard")
|
||||||
|
|||||||
Reference in New Issue
Block a user