federating my verse (iceshrimp & mastodon API compat, read-only)
This commit is contained in:
parent
8dc8190cdf
commit
da93978820
67 changed files with 2743 additions and 649 deletions
Binary file not shown.
Before Width: | Height: | Size: 88 KiB |
|
@ -1,240 +0,0 @@
|
|||
:root {
|
||||
--fg0: #eee;
|
||||
--bg0: #080808;
|
||||
--bg1: #101010;
|
||||
--bg2: #121212;
|
||||
--accent: #b7fd49;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
background-color: var(--bg0);
|
||||
color: var(--fg0);
|
||||
|
||||
font-family: "Inter", sans-serif;
|
||||
}
|
||||
|
||||
#feed {
|
||||
width: 720px;
|
||||
margin: 0 auto;
|
||||
background-color: var(--bg1);
|
||||
}
|
||||
|
||||
.post-container {
|
||||
padding: 20px 32px;
|
||||
border-bottom: 1px solid #8884;
|
||||
transition: background-color .1s;
|
||||
}
|
||||
|
||||
.post-container:hover {
|
||||
background-color: var(--bg2);
|
||||
}
|
||||
|
||||
.post-context {
|
||||
margin-bottom: 8px;
|
||||
padding-left: 58px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
color: var(--accent);
|
||||
opacity: .8;
|
||||
transition: opacity .1s;
|
||||
}
|
||||
|
||||
.post-container:hover .post-context {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.post-context-icon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.post-context a,
|
||||
.post-context a:visited,
|
||||
.post-header-container a,
|
||||
.post-header-container a:visited {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
.post-context a:hover,
|
||||
.post-header-container a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.post-context-time {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
article.post { /* ... */ }
|
||||
|
||||
.post-header-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.post-avatar-container {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.post-avatar {
|
||||
border-radius: 8px;
|
||||
box-shadow: 2px 2px #0004;
|
||||
/* transition: transform .2s ease-out; */
|
||||
}
|
||||
|
||||
/* .post-avatar:hover { */
|
||||
/* transform: scale(1.1); */
|
||||
/* } */
|
||||
|
||||
.post-header {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.post-info {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.post-user-info a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.post-body {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.post-media-container {
|
||||
margin-top: 8px;
|
||||
display: grid;
|
||||
grid-gap: 8px;
|
||||
}
|
||||
|
||||
.post-media-container[data-count="1"] {
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
|
||||
.post-media-container[data-count="2"] {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
|
||||
.post-media-container[data-count="3"] {
|
||||
grid-template-columns: 1fr .5fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
|
||||
.post-media-container[data-count="4"] {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
|
||||
.post-media {
|
||||
border-radius: 12px;
|
||||
background-color: #000;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.post-media a {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.post-media a img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.post-media-container > :nth-child(1) {
|
||||
grid-column: 1/2;
|
||||
grid-row: 1/2;
|
||||
}
|
||||
|
||||
.post-media-container[data-count="3"] > :nth-child(1) {
|
||||
grid-row: 1/3;
|
||||
}
|
||||
|
||||
.post-media-container > :nth-child(2) {
|
||||
grid-column: 2/2;
|
||||
grid-row: 1/2;
|
||||
}
|
||||
|
||||
.post-media-container > :nth-child(3) {
|
||||
grid-column: 1/2;
|
||||
grid-row: 2/2;
|
||||
}
|
||||
|
||||
.post-media-container[data-count="3"] > :nth-child(3) {
|
||||
grid-column: 2/2;
|
||||
grid-row: 2/2;
|
||||
}
|
||||
|
||||
.post-media-container > :nth-child(4) {
|
||||
grid-column: 2/2;
|
||||
grid-row: 2/2;
|
||||
}
|
||||
|
||||
.post-container footer {
|
||||
opacity: .8;
|
||||
transition: opacity .1s;
|
||||
}
|
||||
|
||||
.post-container:hover footer {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.post-reactions {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
button.reaction {
|
||||
padding: 6px 8px;
|
||||
font-size: 1em;
|
||||
background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
/* transition: transform .1s ease-out; */
|
||||
}
|
||||
|
||||
button.reaction:hover,
|
||||
.post-actions button:hover {
|
||||
/* transform: scale(1.1); */
|
||||
background: #8881;
|
||||
}
|
||||
|
||||
button.reaction:active,
|
||||
.post-actions button:active {
|
||||
/* transform: scale(.95); */
|
||||
background: #0001;
|
||||
}
|
||||
|
||||
button.reaction.active,
|
||||
.post-actions button.active {
|
||||
background: var(--accent);
|
||||
color: var(--bg0);
|
||||
}
|
||||
|
||||
.post-actions {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.post-actions button {
|
||||
padding: 6px 8px;
|
||||
font-size: 1em;
|
||||
background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
transition: transform .1s ease-out;
|
||||
}
|
||||
|
||||
.post-actions button .count {
|
||||
opacity: .5;
|
||||
}
|
BIN
public/font/inter/Inter-Black.woff2
Normal file
BIN
public/font/inter/Inter-Black.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-BlackItalic.woff2
Normal file
BIN
public/font/inter/Inter-BlackItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-Bold.woff2
Normal file
BIN
public/font/inter/Inter-Bold.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-BoldItalic.woff2
Normal file
BIN
public/font/inter/Inter-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-ExtraBold.woff2
Normal file
BIN
public/font/inter/Inter-ExtraBold.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-ExtraBoldItalic.woff2
Normal file
BIN
public/font/inter/Inter-ExtraBoldItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-ExtraLight.woff2
Normal file
BIN
public/font/inter/Inter-ExtraLight.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-ExtraLightItalic.woff2
Normal file
BIN
public/font/inter/Inter-ExtraLightItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-Italic.woff2
Normal file
BIN
public/font/inter/Inter-Italic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-Light.woff2
Normal file
BIN
public/font/inter/Inter-Light.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-LightItalic.woff2
Normal file
BIN
public/font/inter/Inter-LightItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-Medium.woff2
Normal file
BIN
public/font/inter/Inter-Medium.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-MediumItalic.woff2
Normal file
BIN
public/font/inter/Inter-MediumItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-Regular.woff2
Normal file
BIN
public/font/inter/Inter-Regular.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-SemiBold.woff2
Normal file
BIN
public/font/inter/Inter-SemiBold.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-SemiBoldItalic.woff2
Normal file
BIN
public/font/inter/Inter-SemiBoldItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-Thin.woff2
Normal file
BIN
public/font/inter/Inter-Thin.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/Inter-ThinItalic.woff2
Normal file
BIN
public/font/inter/Inter-ThinItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-Black.woff2
Normal file
BIN
public/font/inter/InterDisplay-Black.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-BlackItalic.woff2
Normal file
BIN
public/font/inter/InterDisplay-BlackItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-Bold.woff2
Normal file
BIN
public/font/inter/InterDisplay-Bold.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-BoldItalic.woff2
Normal file
BIN
public/font/inter/InterDisplay-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-ExtraBold.woff2
Normal file
BIN
public/font/inter/InterDisplay-ExtraBold.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-ExtraBoldItalic.woff2
Normal file
BIN
public/font/inter/InterDisplay-ExtraBoldItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-ExtraLight.woff2
Normal file
BIN
public/font/inter/InterDisplay-ExtraLight.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-ExtraLightItalic.woff2
Normal file
BIN
public/font/inter/InterDisplay-ExtraLightItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-Italic.woff2
Normal file
BIN
public/font/inter/InterDisplay-Italic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-Light.woff2
Normal file
BIN
public/font/inter/InterDisplay-Light.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-LightItalic.woff2
Normal file
BIN
public/font/inter/InterDisplay-LightItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-Medium.woff2
Normal file
BIN
public/font/inter/InterDisplay-Medium.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-MediumItalic.woff2
Normal file
BIN
public/font/inter/InterDisplay-MediumItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-Regular.woff2
Normal file
BIN
public/font/inter/InterDisplay-Regular.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-SemiBold.woff2
Normal file
BIN
public/font/inter/InterDisplay-SemiBold.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-SemiBoldItalic.woff2
Normal file
BIN
public/font/inter/InterDisplay-SemiBoldItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-Thin.woff2
Normal file
BIN
public/font/inter/InterDisplay-Thin.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterDisplay-ThinItalic.woff2
Normal file
BIN
public/font/inter/InterDisplay-ThinItalic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterVariable-Italic.woff2
Normal file
BIN
public/font/inter/InterVariable-Italic.woff2
Normal file
Binary file not shown.
BIN
public/font/inter/InterVariable.woff2
Normal file
BIN
public/font/inter/InterVariable.woff2
Normal file
Binary file not shown.
92
public/font/inter/LICENSE.txt
Normal file
92
public/font/inter/LICENSE.txt
Normal file
|
@ -0,0 +1,92 @@
|
|||
Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION AND CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
57
public/font/inter/inter.css
Normal file
57
public/font/inter/inter.css
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* Variable fonts usage:
|
||||
:root { font-family: "Inter", sans-serif; }
|
||||
@supports (font-variation-settings: normal) {
|
||||
:root { font-family: "InterVariable", sans-serif; font-optical-sizing: auto; }
|
||||
} */
|
||||
@font-face {
|
||||
font-family: InterVariable;
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
src: url("InterVariable.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: InterVariable;
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-display: swap;
|
||||
src: url("InterVariable-Italic.woff2") format("woff2");
|
||||
}
|
||||
|
||||
/* static fonts */
|
||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 100; font-display: swap; src: url("Inter-Thin.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 100; font-display: swap; src: url("Inter-ThinItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 200; font-display: swap; src: url("Inter-ExtraLight.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 200; font-display: swap; src: url("Inter-ExtraLightItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 300; font-display: swap; src: url("Inter-Light.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 300; font-display: swap; src: url("Inter-LightItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; src: url("Inter-Regular.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 400; font-display: swap; src: url("Inter-Italic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap; src: url("Inter-Medium.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 500; font-display: swap; src: url("Inter-MediumItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; src: url("Inter-SemiBold.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 600; font-display: swap; src: url("Inter-SemiBoldItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; src: url("Inter-Bold.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 700; font-display: swap; src: url("Inter-BoldItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 800; font-display: swap; src: url("Inter-ExtraBold.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 800; font-display: swap; src: url("Inter-ExtraBoldItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: normal; font-weight: 900; font-display: swap; src: url("Inter-Black.woff2") format("woff2"); }
|
||||
@font-face { font-family: "Inter"; font-style: italic; font-weight: 900; font-display: swap; src: url("Inter-BlackItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 100; font-display: swap; src: url("InterDisplay-Thin.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 100; font-display: swap; src: url("InterDisplay-ThinItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 200; font-display: swap; src: url("InterDisplay-ExtraLight.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 200; font-display: swap; src: url("InterDisplay-ExtraLightItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 300; font-display: swap; src: url("InterDisplay-Light.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 300; font-display: swap; src: url("InterDisplay-LightItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 400; font-display: swap; src: url("InterDisplay-Regular.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 400; font-display: swap; src: url("InterDisplay-Italic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 500; font-display: swap; src: url("InterDisplay-Medium.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 500; font-display: swap; src: url("InterDisplay-MediumItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 600; font-display: swap; src: url("InterDisplay-SemiBold.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 600; font-display: swap; src: url("InterDisplay-SemiBoldItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 700; font-display: swap; src: url("InterDisplay-Bold.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 700; font-display: swap; src: url("InterDisplay-BoldItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 800; font-display: swap; src: url("InterDisplay-ExtraBold.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 800; font-display: swap; src: url("InterDisplay-ExtraBoldItalic.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 900; font-display: swap; src: url("InterDisplay-Black.woff2") format("woff2"); }
|
||||
@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 900; font-display: swap; src: url("InterDisplay-BlackItalic.woff2") format("woff2"); }
|
|
@ -1,107 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
experimenting with post layouts here!
|
||||
don't expect anything too flashy ;3
|
||||
|
||||
ari melody, 2024
|
||||
-->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title></title>
|
||||
<link href="css/style.css" rel="stylesheet">
|
||||
<script type="application/javascript" src="script/main.mjs" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<audio id="sound-success" src="sound/success.wav"></audio>
|
||||
<header>
|
||||
|
||||
</header>
|
||||
<main>
|
||||
<div id="feed">
|
||||
<!--
|
||||
<div class="post-container" aria-label="ari; hello world!~; 02:12:06">
|
||||
<div class="post-context">
|
||||
<span class="post-context-icon">🔁</span>
|
||||
<span class="post-context-action">
|
||||
<a href="/@ari">ari 💫</a> boosted this post.
|
||||
</span>
|
||||
<span class="post-context-time">
|
||||
<time title="6/3/2024, 2:12:06 AM">2m ago</time>
|
||||
</span>
|
||||
</div>
|
||||
<article class="post">
|
||||
<div class="post-header-container">
|
||||
<a href="/@ari" class="post-avatar-container">
|
||||
<img src="avatar/ari.jpg" alt="" width="48" height="48" class="post-avatar" loading="lazy" decoding="async">
|
||||
</a>
|
||||
<header class="post-header">
|
||||
<div class="post-user-info">
|
||||
<a href="/@ari" class="name">ari 💫</a>
|
||||
<span class="username">@ari</span>
|
||||
</div>
|
||||
<div class="post-info">
|
||||
<a href="/post/21c892b23701" class="created-at">
|
||||
<time title="6/3/2024, 2:11:58 AM">10m ago</time>
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
<div class="post-body">
|
||||
<span class="post-content">hello world!~</span>
|
||||
<div class="post-media-container" data-count="3">
|
||||
<div class="post-media image">
|
||||
<a href="media/ariyeah-button.png">
|
||||
<img src="media/ariyeah-button.png" alt="custom miiverse "yeah!" button" loading="lazy" decoding="async">
|
||||
</a>
|
||||
</div>
|
||||
<div class="post-media image">
|
||||
<a href="media/beer.jpg">
|
||||
<img src="media/beer.jpg" alt="barney calhoun with beer" loading="lazy" decoding="async">
|
||||
</a>
|
||||
</div>
|
||||
<div class="post-media image">
|
||||
<a href="media/duck.jpg">
|
||||
<img src="media/duck.jpg" alt="big rubber duck" loading="lazy" decoding="async">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="post-footer">
|
||||
<div class="post-reactions">
|
||||
<button type="button" class="reaction">
|
||||
<span>⭐</span>
|
||||
<span class="count">52</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="post-actions">
|
||||
<button type="button" class="reply" aria-label="Reply" title="Reply">
|
||||
<span>🗨️</span>
|
||||
<span class="count">7</span>
|
||||
</button>
|
||||
<button type="button" class="boost" aria-label="Boost" title="Boost">
|
||||
<span>🔁</span>
|
||||
<span class="count">13</span>
|
||||
</button>
|
||||
<button type="button" class="favourite" aria-label="Favourite" title="Favourite">
|
||||
<span>⭐</span>
|
||||
</button>
|
||||
<button type="button" class="react" aria-label="React" title="React">
|
||||
<span>😃</span>
|
||||
</button>
|
||||
<button type="button" class="quote" aria-label="Quote" title="Quote">
|
||||
<span>🗣️</span>
|
||||
</button>
|
||||
<button type="button" class="more" aria-label="More" title="More">
|
||||
<span>🛠️</span>
|
||||
</button>
|
||||
</div>
|
||||
</footer>
|
||||
</article>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
|
@ -1,302 +0,0 @@
|
|||
const aria_safe_regex = /([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF]|[\r])/g;
|
||||
const INSTANCE_URL = "soc.arimelody.me";
|
||||
|
||||
const sounds = {
|
||||
"default": new Audio("sound/log.ogg"),
|
||||
"post": new Audio("sound/success.ogg"),
|
||||
"boost": new Audio("sound/hello.ogg"),
|
||||
};
|
||||
|
||||
const actors = {
|
||||
"@ari": {
|
||||
"url": "https://soc.arimelody.me/@ari",
|
||||
"name": "ari 💫",
|
||||
"avatar": "avatar/ari.jpg",
|
||||
}
|
||||
};
|
||||
|
||||
const test_post = {
|
||||
"context": {
|
||||
"type": "boost",
|
||||
"by": "@ari",
|
||||
"at": 1718513838624,
|
||||
},
|
||||
"author": "@ari",
|
||||
"url": "/post/21c892b23701",
|
||||
"at": 1718513988384,
|
||||
"content": "hello world!~",
|
||||
"media": [
|
||||
{ "url": "media/ariyeah-button.png", "alt": "custom miiverse \"yeah!\" button" },
|
||||
{ "url": "media/beer.jpg", "alt": "barney calhoun with beer" },
|
||||
{ "url": "media/duck.jpg", "alt": "big rubber duck" },
|
||||
],
|
||||
"replies": 7,
|
||||
"boosts": 13,
|
||||
"reactions": [
|
||||
{ "react": "⭐", "count": "52" },
|
||||
{ "react": "❤️", "count": "9" },
|
||||
],
|
||||
};
|
||||
|
||||
const feed = document.getElementById("feed");
|
||||
|
||||
function render_post(data) {
|
||||
// TODO: please god just use or make a library to build this
|
||||
|
||||
const actor = actors[data.author];
|
||||
if (!actor) return;
|
||||
const date = new Date(data.at);
|
||||
|
||||
const post = document.createElement("article");
|
||||
post.classList.add("post-container");
|
||||
post.ariaLabel = actor.name.replace(aria_safe_regex, "").trim() + "; " + data.content + "; " + date.toLocaleTimeString();
|
||||
|
||||
if (data.context && data.context.by && actors[data.context.by]) {
|
||||
// post context
|
||||
const post_context = document.createElement("div");
|
||||
post_context.classList.add("post-context");
|
||||
|
||||
if (data.context.type == "boost") {
|
||||
const post_context_icon = document.createElement("span");
|
||||
post_context_icon.classList.add("post-context-icon");
|
||||
post_context_icon.innerText = "🔁";
|
||||
post_context.appendChild(post_context_icon);
|
||||
|
||||
const post_context_action = document.createElement("span");
|
||||
post_context_action.classList.add("post-context-action");
|
||||
const actor = actors[data.context.by];
|
||||
post_context_action.innerHTML = `boosted by <a href="${actor.url}">${actor.name}</a>`;
|
||||
post_context.appendChild(post_context_action);
|
||||
|
||||
const post_context_time = document.createElement("span");
|
||||
post_context_time.classList.add("post-context-time");
|
||||
post_context_time.innerHTML = `<time>${new Date(data.context.at).toLocaleString()}</time>`;
|
||||
post_context.appendChild(post_context_time);
|
||||
}
|
||||
|
||||
post.appendChild(post_context);
|
||||
}
|
||||
|
||||
// the actual post
|
||||
// article.post
|
||||
const post_article = document.createElement("article");
|
||||
|
||||
const post_header_container = document.createElement("div");
|
||||
post_header_container.classList.add("post-header-container");
|
||||
const post_avatar_container = document.createElement("a");
|
||||
post_avatar_container.classList.add("post-avatar-container");
|
||||
post_avatar_container.href = actor.url;
|
||||
const post_avatar = document.createElement("img");
|
||||
post_avatar.classList.add("post-avatar");
|
||||
post_avatar.src = actor.avatar;
|
||||
post_avatar.alt = "";
|
||||
post_avatar.width = 48;
|
||||
post_avatar.height = 48;
|
||||
post_avatar.loading = "lazy";
|
||||
post_avatar.decoding = "async";
|
||||
post_avatar_container.appendChild(post_avatar);
|
||||
post_header_container.appendChild(post_avatar_container);
|
||||
|
||||
const post_header = document.createElement("header");
|
||||
post_header.classList.add("post-header");
|
||||
const post_user_info = document.createElement("div");
|
||||
post_user_info.classList.add("post-user-info");
|
||||
const post_user_info_name = document.createElement("a");
|
||||
post_user_info_name.classList.add("name");
|
||||
post_user_info_name.href = actor.url;
|
||||
post_user_info_name.innerText = actor.name
|
||||
post_user_info.appendChild(post_user_info_name);
|
||||
const post_user_info_username = document.createElement("span");
|
||||
post_user_info_username.classList.add("username");
|
||||
post_user_info_username.href = actor.url;
|
||||
post_user_info_username.innerText = data.author
|
||||
post_user_info.appendChild(post_user_info_username);
|
||||
post_header.appendChild(post_user_info);
|
||||
const post_info = document.createElement("div");
|
||||
post_info.classList.add("post-info");
|
||||
const post_info_time = document.createElement("a");
|
||||
post_info_time.classList.add("created-at");
|
||||
const post_date = new Date(data.at);
|
||||
post_info_time.innerHTML = `<time title=${post_date.toLocaleString()}>${post_date.toLocaleString()}</time>`;
|
||||
post_info_time.href = post.url;
|
||||
post_info.appendChild(post_info_time);
|
||||
post_header.appendChild(post_info);
|
||||
post_header_container.appendChild(post_header);
|
||||
|
||||
post_article.appendChild(post_header_container);
|
||||
|
||||
|
||||
const post_body = document.createElement("div");
|
||||
post_body.classList.add("post-body");
|
||||
|
||||
const post_content = document.createElement("span");
|
||||
post_content.classList.add("post-content");
|
||||
post_content.innerText = data.content;
|
||||
post_body.appendChild(post_content);
|
||||
|
||||
const media_container = document.createElement("div");
|
||||
media_container.classList.add("post-media-container");
|
||||
media_container.dataset.count = data.media.length;
|
||||
data.media.forEach(media => {
|
||||
const media_item = document.createElement("div");
|
||||
media_item.classList.add("post-media");
|
||||
const link = document.createElement("a");
|
||||
link.href = media.url;
|
||||
const source = document.createElement("img");
|
||||
source.src = media.url;
|
||||
source.alt = media.alt;
|
||||
source.loading = "lazy";
|
||||
source.decoding = "async";
|
||||
link.appendChild(source);
|
||||
media_item.appendChild(link);
|
||||
media_container.appendChild(media_item);
|
||||
});
|
||||
post_body.appendChild(media_container);
|
||||
|
||||
post_article.appendChild(post_body);
|
||||
|
||||
|
||||
const post_footer = document.createElement("footer");
|
||||
post_footer.classList.add("post-footer");
|
||||
|
||||
const post_reactions = document.createElement("div");
|
||||
post_reactions.classList.add("post-reactions");
|
||||
data.reactions.forEach(reaction => {
|
||||
const btn = document.createElement("button");
|
||||
btn.classList.add("reaction");
|
||||
btn.type = "button";
|
||||
const emote = document.createElement("span");
|
||||
emote.innerText = reaction.react;
|
||||
btn.appendChild(emote);
|
||||
const count = document.createElement("span");
|
||||
count.classList.add("count");
|
||||
count.innerText = reaction.count;
|
||||
btn.appendChild(count);
|
||||
post_reactions.appendChild(btn);
|
||||
});
|
||||
post_footer.appendChild(post_reactions);
|
||||
|
||||
const post_actions = document.createElement("div");
|
||||
post_actions.classList.add("post-actions");
|
||||
|
||||
const reply_button = document.createElement("button");
|
||||
reply_button.type = "button";
|
||||
reply_button.ariaLabel = "Reply";
|
||||
reply_button.title = "Reply";
|
||||
reply_button.innerHTML = `<span>🗨️</span><span class="count">${data.replies}</count>`;
|
||||
post_actions.appendChild(reply_button);
|
||||
|
||||
const boost_button = document.createElement("button");
|
||||
boost_button.type = "button";
|
||||
boost_button.ariaLabel = "Boost";
|
||||
boost_button.title = "Boost";
|
||||
boost_button.innerHTML = `<span>🔁</span><span class="count">${data.boosts}</count>`;
|
||||
post_actions.appendChild(boost_button);
|
||||
|
||||
const fav_button = document.createElement("button");
|
||||
fav_button.type = "button";
|
||||
fav_button.ariaLabel = "Favourite";
|
||||
fav_button.title = "Favourite";
|
||||
fav_button.innerText = "⭐";
|
||||
post_actions.appendChild(fav_button);
|
||||
|
||||
const react_button = document.createElement("button");
|
||||
react_button.type = "button";
|
||||
react_button.ariaLabel = "React";
|
||||
react_button.title = "React";
|
||||
react_button.innerText = "😃";
|
||||
post_actions.appendChild(react_button);
|
||||
|
||||
const quote_button = document.createElement("button");
|
||||
quote_button.type = "button";
|
||||
quote_button.ariaLabel = "Quote";
|
||||
quote_button.title = "Quote";
|
||||
quote_button.innerText = "🗣️";
|
||||
post_actions.appendChild(quote_button);
|
||||
|
||||
const more_button = document.createElement("button");
|
||||
more_button.type = "button";
|
||||
more_button.ariaLabel = "More";
|
||||
more_button.title = "More";
|
||||
more_button.innerText = "⚒️";
|
||||
post_actions.appendChild(more_button);
|
||||
|
||||
post_footer.appendChild(post_actions);
|
||||
|
||||
post_article.appendChild(post_footer);
|
||||
|
||||
|
||||
post.appendChild(post_article);
|
||||
|
||||
return post;
|
||||
};
|
||||
|
||||
function hook_post_listeners(post) {
|
||||
post.querySelectorAll("button").forEach(button => {
|
||||
button.addEventListener("click", () => {
|
||||
if (button.classList.contains("reaction")) {
|
||||
toggle_reaction(button);
|
||||
}
|
||||
|
||||
switch (button.ariaLabel) {
|
||||
case "Reply":
|
||||
play_sound("post");
|
||||
break;
|
||||
|
||||
case "Boost":
|
||||
play_sound("boost");
|
||||
break;
|
||||
|
||||
case "Favourite":
|
||||
post.querySelectorAll("button.reaction").forEach(reaction => {
|
||||
if (!reaction.innerText.startsWith("⭐")) return;
|
||||
toggle_reaction(reaction);
|
||||
});
|
||||
play_sound();
|
||||
break;
|
||||
|
||||
default:
|
||||
play_sound();
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function toggle_reaction(reaction) {
|
||||
const was_active = reaction.classList.contains("active");
|
||||
reaction.classList.toggle("active");
|
||||
const count = reaction.querySelector(".count");
|
||||
count.innerText = Number(count.innerText) + (was_active ? -1 : 1);
|
||||
}
|
||||
|
||||
function load_content() {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const post = render_post(test_post);
|
||||
feed.appendChild(post);
|
||||
hook_post_listeners(post);
|
||||
}
|
||||
}
|
||||
|
||||
function play_sound(name) {
|
||||
if (!name) name = "default";
|
||||
const sound = sounds[name];
|
||||
if (!sound) {
|
||||
console.warn(`Attempted to play sound "${name}", which does not exist!`);
|
||||
return;
|
||||
}
|
||||
sound.pause();
|
||||
sound.currentTime = 0;
|
||||
sound.play();
|
||||
}
|
||||
|
||||
feed.querySelectorAll(".post-container").forEach(post => {
|
||||
hook_post_listeners(post);
|
||||
});
|
||||
load_content();
|
||||
|
||||
document.addEventListener("scroll", event => {
|
||||
while (window.innerHeight + window.scrollY >= document.body.offsetHeight - 1000) {
|
||||
load_content();
|
||||
}
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue