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 - [X] sidebar on mobile needs to show/hide via a button
- [ ] clean up after initial implementation - [ ] clean up after initial implementation
- [X] split the monolithic talk.html up - [X] split the monolithic talk.html up
- [X] rename talk => chat
- [ ] chat message processing - [ ] chat message processing
- [X] auto-link urls - [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)` - [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; 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 */
.icon.download { .icon.download {
box-sizing: border-box; box-sizing: border-box;

View file

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

View file

@ -1,22 +1,22 @@
<div id="talk" class="tab"> <div id="chat" class="tab">
<input <input
type="radio" type="radio"
name="top-level-tabs" name="top-level-tabs"
id="talk-tab-input" id="chat-tab-input"
class="tab-switch" class="tab-switch"
data-hash="/talk" data-hash="/chat"
/> />
<label for="talk-tab-input" class="tab-label" <label for="chat-tab-input" class="tab-label"
><div class="icon talk"></div> ><div class="icon chat"></div>
<div class="label">Talk</div> <div class="label">Chat</div>
</label> </label>
<div class="tab-content"> <div class="tab-content">
<style> <style>
<!-- #include file="./talk.css" --> <!-- #include file="./chat.css" -->
</style> </style>
<script src="/js/external/mimetypes.js" type="text/javascript"></script> <script src="/js/external/mimetypes.js" type="text/javascript"></script>
<script src="/js/external/punycode.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"> <div class="sidebar resizable">
<input type="checkbox" id="sidebar-toggle" /> <input type="checkbox" id="sidebar-toggle" />
<label id="sidebar-toggle-icon" for="sidebar-toggle"> <label id="sidebar-toggle-icon" for="sidebar-toggle">
@ -73,7 +73,7 @@
); );
new_room_name_input.value = ""; 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"; 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-container iframe ${item_type.toLowerCase().indexOf("track") === 0 ? "short" : "square"} tidal">
<div class="embed-actions-container"> <div class="embed-actions-container">
<button class="icon plus" onclick="console.log(\"close\");"/> <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> </div>
<iframe <iframe
src="https://embed.tidal.com/${item_type.at(-1) === "s" ? item_type : `${item_type}s`}/${item_id}" 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-container iframe ${!item_type || item_type.toLowerCase().indexOf("track") === 0 ? "short" : "square"} spotify rounded">
<div class="embed-actions-container"> <div class="embed-actions-container">
<button class="icon plus" onclick="console.log(\"close\");"/> <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> </div>
<iframe <iframe
src="https://open.spotify.com/embed/${item_type ?? "track"}/${item_id}" 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-container iframe ${action === "shorts" ? "vertical" : "letterbox"} youtube">
<div class="embed-actions-container"> <div class="embed-actions-container">
<button class="icon plus" onclick="console.log(\"close\");"/> <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> </div>
<iframe <iframe
src="https://www.youtube.com/embed/${video_id}" 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-container iframe letterbox vimeo">
<div class="embed-actions-container"> <div class="embed-actions-container">
<button class="icon plus" onclick="console.log(\"close\");"/> <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> </div>
<iframe <iframe
src="https://player.vimeo.com/video/${video_id}" src="https://player.vimeo.com/video/${video_id}"
@ -450,7 +450,7 @@ async function update_chat_rooms() {
for (const room of rooms) { for (const room of rooms) {
room_list.insertAdjacentHTML( room_list.insertAdjacentHTML(
"beforeend", "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 hash = window.location.hash;
const talk_in_url = hash.indexOf("#/talk") === 0; const chat_in_url = hash.indexOf("#/chat") === 0;
if (!talk_in_url) { if (!chat_in_url) {
return; return;
} }
const first_room_id = document.querySelector("li.room")?.id.substring(14); const first_room_id = document.querySelector("li.room")?.id.substring(14);
// #/talk/room/{room_id} // #/chat/room/{room_id}
// ^ 12 // ^ 12
const room_id = hash.substring(12) || first_room_id; 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"); const room_chat_container = document.getElementById("room-chat-container");
if (room_chat_container.dataset.room_id !== room_id) { 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; room_chat_container.dataset.room_id = room_id;
load_room(room_id); load_room(room_id);
} }

File diff suppressed because it is too large Load diff

View file

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