refactor: talk => chat

This commit is contained in:
Andy Burke 2025-09-05 11:03:53 -07:00
parent b6b4fefa34
commit 525568d368
8 changed files with 1675 additions and 83 deletions

View file

@ -35,6 +35,7 @@ feature discussions.
- [X] sidebar on mobile needs to show/hide via a button
- [ ] clean up after initial implementation
- [X] split the monolithic talk.html up
- [X] rename talk => chat
- [ ] chat message processing
- [X] auto-link urls
- [X] use this regex: `(?:(?<protocol>[a-zA-Z]+):)?(?:\/\/)?(?:(?<auth>(?<username>\S.+)\:(?<password>.+))\@)?(?<host>(?:(?<hostname>[-a-zA-Z0-9\.]+)\.)?(?<domain>(?:[-a-zA-Z0-9]+?\.(?<tld>[-a-zA-Z0-9]{2,64}))|localhost)(?:\:(?<port>[0-9]{1,6}))?)\b(?<path>[-a-zA-Z0-9@:%_{}\[\]<>\(\)\+.~&\/="]*?(?<extension>\.[^\.?/#"\n<>]+)?)(?:\?(?<query>[a-zA-Z0-9!$%&<>()*+,-\.\/\:\;\=\?\@_~"]+))?(?:#(?<hash>[a-zA-Z0-9!$&'()*+,-\.\/\:\;\=\?\@_~"]*?))?(?:$|\s)`

View file

@ -510,6 +510,44 @@ body[data-perms*="rooms.create"] [data-requires-permission="rooms.create"] {
top: 2px;
}
/* ICON - CHAT */
.icon.chat {
box-sizing: border-box;
position: relative;
display: block;
transform: scale(var(--icon-scale, 1));
width: 20px;
height: 16px;
border: 2px solid;
border-bottom: 0;
box-shadow:
-6px 8px 0 -6px,
6px 8px 0 -6px;
}
.icon.chat::after,
.icon.chat::before {
content: "";
display: block;
box-sizing: border-box;
position: absolute;
width: 8px;
}
.icon.chat::before {
border: 2px solid;
border-top-color: transparent;
border-bottom-left-radius: 20px;
right: 4px;
bottom: -6px;
height: 6px;
}
.icon.chat::after {
height: 2px;
background: currentColor;
box-shadow: 0 4px 0 0;
left: 4px;
top: 4px;
}
/* ICON - DOWNLOAD */
.icon.download {
box-sizing: border-box;

View file

@ -14,6 +14,7 @@
<script src="./js/audioplayer.js" type="text/javascript"></script>
<script src="./js/datetimeutils.js" type="text/javascript"></script>
<script src="./js/locationchange.js" type="text/javascript"></script>
<script src="./js/notifications.js" type="text/javascript"></script>
<script src="./js/totp.js" type="text/javascript"></script>
<script src="./js/api.js" type="text/javascript"></script>
<script src="./js/smartforms.js" type="text/javascript"></script>

View file

@ -1,4 +1,4 @@
#talk .tab-content {
#chat .tab-content {
display: grid;
grid-template-columns: auto 1fr;
}
@ -34,7 +34,7 @@
color: var(--accent);
}
#talk .sidebar {
#chat .sidebar {
position: relative;
width: min-content;
min-width: 10rem;
@ -43,24 +43,24 @@
padding: 0.5rem;
}
#talk .sidebar #sidebar-toggle,
#talk .sidebar #sidebar-toggle-icon {
#chat .sidebar #sidebar-toggle,
#chat .sidebar #sidebar-toggle-icon {
opacity: 0;
display: none;
}
#talk .sidebar .title {
#chat .sidebar .title {
text-transform: uppercase;
font-size: small;
font-weight: bold;
line-height: 2rem;
}
#talk #room-chat-container {
#chat #room-chat-container {
position: relative;
}
#talk #room-chat-content {
#chat #room-chat-content {
overflow-y: scroll;
position: absolute;
top: 0;
@ -70,7 +70,7 @@
padding: 0.5rem;
}
#talk #room-chat-entry-container {
#chat #room-chat-entry-container {
position: absolute;
bottom: 0;
left: 0;
@ -79,7 +79,7 @@
padding: 1rem;
}
#talk #room-chat-entry-container form {
#chat #room-chat-entry-container form {
position: absolute;
top: 0;
left: 0;
@ -90,13 +90,13 @@
padding: 0.75rem;
}
#talk #room-chat-entry-container form input[type="file"] {
#chat #room-chat-entry-container form input[type="file"] {
opacity: 0;
display: none;
}
#talk #room-chat-entry-container form button,
#talk #room-chat-entry-container form label {
#chat #room-chat-entry-container form button,
#chat #room-chat-entry-container form label {
position: relative;
top: inherit;
font-size: inherit;
@ -110,7 +110,7 @@
border: 1px solid var(--text);
}
#talk #room-chat-entry-container form textarea {
#chat #room-chat-entry-container form textarea {
width: 100%;
flex-grow: 1;
background: inherit;
@ -118,7 +118,7 @@
border-radius: var(--border-radius);
}
#talk .message-container {
#chat .message-container {
position: relative;
transition: all 0.33s;
background: rgba(255, 255, 255, 0.03);
@ -127,27 +127,27 @@
border-radius: var(--border-radius);
}
#talk .message-container.user-tick.time-tick + .message-container.user-tick.time-tick,
#talk .message-container.user-tick.time-tock + .message-container.user-tick.time-tock,
#talk .message-container.user-tock.time-tick + .message-container.user-tock.time-tick,
#talk .message-container.user-tock.time-tock + .message-container.user-tock.time-tock {
#chat .message-container.user-tick.time-tick + .message-container.user-tick.time-tick,
#chat .message-container.user-tick.time-tock + .message-container.user-tick.time-tock,
#chat .message-container.user-tock.time-tick + .message-container.user-tock.time-tick,
#chat .message-container.user-tock.time-tock + .message-container.user-tock.time-tock {
margin-top: 0;
padding: 0 2px;
}
#talk
#chat
.message-container.user-tick.time-tick
+ .message-container.user-tick.time-tick
.info-container,
#talk
#chat
.message-container.user-tick.time-tock
+ .message-container.user-tick.time-tock
.info-container,
#talk
#chat
.message-container.user-tock.time-tick
+ .message-container.user-tock.time-tick
.info-container,
#talk
#chat
.message-container.user-tock.time-tock
+ .message-container.user-tock.time-tock
.info-container {
@ -157,11 +157,11 @@
margin: 0;
}
#talk .message-container.sending {
#chat .message-container.sending {
opacity: 0.75;
}
#talk .message-container .message-actions-container {
#chat .message-container .message-actions-container {
position: absolute;
top: 0.5rem;
right: 0.5rem;
@ -169,7 +169,7 @@
flex-direction: row;
}
#talk .message-container .message-actions-container .message-action {
#chat .message-container .message-actions-container .message-action {
opacity: 0;
transition: 0.2s ease-in-out;
width: 0;
@ -182,16 +182,16 @@
text-align: center;
}
#talk .message-container .message-actions-container label {
#chat .message-container .message-actions-container label {
cursor: pointer;
}
#talk .message-container .message-actions-container input[type="checkbox"] {
#chat .message-container .message-actions-container input[type="checkbox"] {
opacity: 0;
display: none;
}
#talk
#chat
.message-container
.message-actions-container
input[type="checkbox"]:checked
@ -200,17 +200,17 @@
width: 4rem;
}
#talk .message-container .message-actions-container .message-action .action-name {
#chat .message-container .message-actions-container .message-action .action-name {
font-size: x-small;
}
#talk .message-container .info-container {
#chat .message-container .info-container {
display: flex;
margin-bottom: -1.75rem;
height: 3.75rem;
}
#talk .message-container .info-container .avatar-container {
#chat .message-container .info-container .avatar-container {
display: inline-block;
margin: 0 4px;
width: 3rem;
@ -219,41 +219,41 @@
overflow: hidden;
}
#talk .message-container .info-container .avatar-container img {
#chat .message-container .info-container .avatar-container img {
width: 100%;
}
#talk .message-container .info-container .username-container {
#chat .message-container .info-container .username-container {
margin: 0 4px;
font-weight: bold;
}
#talk .message-container .info-container .datetime-container {
#chat .message-container .info-container .datetime-container {
margin: 0 4px;
}
#talk .message-container .info-container .datetime-container .long {
#chat .message-container .info-container .datetime-container .long {
font-size: x-small;
text-transform: uppercase;
}
#talk .message-container .info-container .datetime-container .short {
#chat .message-container .info-container .datetime-container .short {
font-size: xx-small;
visibility: hidden;
display: none;
}
#talk .message-container .message-content-container {
#chat .message-container .message-content-container {
padding-left: 8rem;
}
#talk .embed-container {
#chat .embed-container {
position: relative;
width: 100%;
max-width: 640px;
}
#talk .embed-container .embed-actions-container {
#chat .embed-container .embed-actions-container {
position: absolute;
z-index: 100;
top: 0.25rem;
@ -265,31 +265,31 @@
opacity: 0;
}
#talk .embed-container audio {
#chat .embed-container audio {
width: 100%;
}
#talk .embed-container.rounded {
#chat .embed-container.rounded {
border-radius: 6px;
}
#talk .embed-container.short {
#chat .embed-container.short {
height: 120px;
overflow: hidden;
overflow-y: auto;
}
#talk .embed-container.tidal {
#chat .embed-container.tidal {
border-radius: 12px;
}
#talk .embed-container.vertical {
#chat .embed-container.vertical {
max-width: 320px;
overflow: hidden;
aspect-ratio: 9 / 16 !important;
}
#talk .embed-container.letterbox {
#chat .embed-container.letterbox {
/* height: 0; */
overflow: hidden;
overflow-y: auto;
@ -297,14 +297,14 @@
aspect-ratio: 16 / 9 !important;
}
#talk .embed-container.square {
#chat .embed-container.square {
overflow: hidden;
overflow-y: auto;
aspect-ratio: 1 / 1 !important;
}
#talk .embed-container iframe,
#talk .embed-container video {
#chat .embed-container iframe,
#chat .embed-container video {
position: absolute;
top: 0;
left: 0;
@ -317,7 +317,7 @@
}
@media screen and (max-width: 768px) {
#talk .sidebar {
#chat .sidebar {
z-index: 100;
background: var(--bg);
position: absolute;
@ -330,7 +330,7 @@
transition: all ease-in-out 0.33s;
}
#talk .sidebar #sidebar-toggle-icon {
#chat .sidebar #sidebar-toggle-icon {
opacity: 1;
display: block;
position: absolute;
@ -343,20 +343,20 @@
padding: 0.5rem;
}
#talk .sidebar .icon {
#chat .sidebar .icon {
transition: all ease-in-out 0.33s;
}
#talk .sidebar:has(#sidebar-toggle:checked) {
#chat .sidebar:has(#sidebar-toggle:checked) {
left: 0;
}
#talk .sidebar:has(#sidebar-toggle:checked) #sidebar-toggle-icon {
#chat .sidebar:has(#sidebar-toggle:checked) #sidebar-toggle-icon {
right: 0;
rotate: 180deg;
}
#talk #room-chat-container {
#chat #room-chat-container {
position: absolute;
top: 0;
left: 0;
@ -364,26 +364,26 @@
bottom: 0;
}
#talk #room-chat-container #room-chat-entry-container,
#talk #room-chat-container #room-chat-entry-container form {
#chat #room-chat-container #room-chat-entry-container,
#chat #room-chat-container #room-chat-entry-container form {
padding: 0.25rem;
}
#talk #room-chat-container #room-chat-entry-container form button,
#talk #room-chat-container #room-chat-entry-container form label {
#chat #room-chat-container #room-chat-entry-container form button,
#chat #room-chat-container #room-chat-entry-container form label {
margin: 0 0.5rem;
}
#talk .message-container .message-content-container {
#chat .message-container .message-content-container {
padding-left: 4rem;
}
#talk .message-container .info-container .datetime-container .long {
#chat .message-container .info-container .datetime-container .long {
display: none;
visibility: hidden;
}
#talk .message-container .info-container .datetime-container .short {
#chat .message-container .info-container .datetime-container .short {
display: inline-block;
visibility: visible;
}

View file

@ -1,22 +1,22 @@
<div id="talk" class="tab">
<div id="chat" class="tab">
<input
type="radio"
name="top-level-tabs"
id="talk-tab-input"
id="chat-tab-input"
class="tab-switch"
data-hash="/talk"
data-hash="/chat"
/>
<label for="talk-tab-input" class="tab-label"
><div class="icon talk"></div>
<div class="label">Talk</div>
<label for="chat-tab-input" class="tab-label"
><div class="icon chat"></div>
<div class="label">Chat</div>
</label>
<div class="tab-content">
<style>
<!-- #include file="./talk.css" -->
<!-- #include file="./chat.css" -->
</style>
<script src="/js/external/mimetypes.js" type="text/javascript"></script>
<script src="/js/external/punycode.js" type="text/javascript"></script>
<script src="/tabs/talk/talk.js" type="text/javascript"></script>
<script src="/tabs/chat/chat.js" type="text/javascript"></script>
<div class="sidebar resizable">
<input type="checkbox" id="sidebar-toggle" />
<label id="sidebar-toggle-icon" for="sidebar-toggle">
@ -73,7 +73,7 @@
);
new_room_name_input.value = "";
window.location.hash = `/talk/room/${new_room.id}`;
window.location.hash = `/chat/room/${new_room.id}`;
room_create_form.style["height"] = "0";
};
}

View file

@ -34,7 +34,7 @@ const URL_MATCH_HANDLERS = [
<div class="embed-container iframe ${item_type.toLowerCase().indexOf("track") === 0 ? "short" : "square"} tidal">
<div class="embed-actions-container">
<button class="icon plus" onclick="console.log(\"close\");"/>
<button class="icon talk" onclick="console.log(\"stop\");"/>
<button class="icon pause" onclick="console.log(\"stop\");"/>
</div>
<iframe
src="https://embed.tidal.com/${item_type.at(-1) === "s" ? item_type : `${item_type}s`}/${item_id}"
@ -68,7 +68,7 @@ const URL_MATCH_HANDLERS = [
<div class="embed-container iframe ${!item_type || item_type.toLowerCase().indexOf("track") === 0 ? "short" : "square"} spotify rounded">
<div class="embed-actions-container">
<button class="icon plus" onclick="console.log(\"close\");"/>
<button class="icon talk" onclick="console.log(\"stop\");"/>
<button class="icon pause" onclick="console.log(\"stop\");"/>
</div>
<iframe
src="https://open.spotify.com/embed/${item_type ?? "track"}/${item_id}"
@ -102,7 +102,7 @@ const URL_MATCH_HANDLERS = [
<div class="embed-container iframe ${action === "shorts" ? "vertical" : "letterbox"} youtube">
<div class="embed-actions-container">
<button class="icon plus" onclick="console.log(\"close\");"/>
<button class="icon talk" onclick="console.log(\"stop\");"/>
<button class="icon pause" onclick="console.log(\"stop\");"/>
</div>
<iframe
src="https://www.youtube.com/embed/${video_id}"
@ -137,7 +137,7 @@ const URL_MATCH_HANDLERS = [
<div class="embed-container iframe letterbox vimeo">
<div class="embed-actions-container">
<button class="icon plus" onclick="console.log(\"close\");"/>
<button class="icon talk" onclick="console.log(\"stop\");"/>
<button class="icon pause" onclick="console.log(\"stop\");"/>
</div>
<iframe
src="https://player.vimeo.com/video/${video_id}"
@ -450,7 +450,7 @@ async function update_chat_rooms() {
for (const room of rooms) {
room_list.insertAdjacentHTML(
"beforeend",
`<li id="room-selector-${room.id}" class="room"><a href="#/talk/room/${room.id}">${room.name}</a></li>`,
`<li id="room-selector-${room.id}" class="room"><a href="#/chat/room/${room.id}">${room.name}</a></li>`,
);
}
@ -466,14 +466,14 @@ function check_for_room_in_url() {
}
const hash = window.location.hash;
const talk_in_url = hash.indexOf("#/talk") === 0;
if (!talk_in_url) {
const chat_in_url = hash.indexOf("#/chat") === 0;
if (!chat_in_url) {
return;
}
const first_room_id = document.querySelector("li.room")?.id.substring(14);
// #/talk/room/{room_id}
// #/chat/room/{room_id}
// ^ 12
const room_id = hash.substring(12) || first_room_id;
@ -485,7 +485,7 @@ function check_for_room_in_url() {
const room_chat_container = document.getElementById("room-chat-container");
if (room_chat_container.dataset.room_id !== room_id) {
window.location.hash = `/talk/room/${room_id}`;
window.location.hash = `/chat/room/${room_id}`;
room_chat_container.dataset.room_id = room_id;
load_room(room_id);
}

File diff suppressed because it is too large Load diff

View file

@ -135,11 +135,8 @@
</style>
<div class="tabs">
<!-- #include file="./home/home.html" -->
<!-- #include file="./talk/talk.html" -->
<!-- #include file="./exchange/exchange.html" -->
<!-- #include file="./chat/chat.html" -->
<!-- #include file="./resources/resources.html" -->
<!-- #include file="./calendar/calendar.html" -->
<!-- #include file="./work/work.html" -->
<!-- #include file="./profile/profile.html" -->
</div>