New mobile nav. Removed old cruft.
This commit is contained in:
parent
20907bede6
commit
6c9f5f12fe
9 changed files with 106 additions and 253 deletions
62
README.md
62
README.md
|
@ -1,59 +1,15 @@
|
||||||
# Yo, Sup?
|
# Yo Sup
|
||||||
|
|
||||||
Yo Sup? or simply "Yo" for short is a web client for the Nostr protocol. Its
|
|
||||||
aim is to be as good of an experience (if not better than) as Twitter. Note Yo
|
|
||||||
will not be the same as Twitter and will not implement all of it's features.
|
|
||||||
Nor will Yo try to implement all of Nostr's features as there are many.
|
|
||||||
|
|
||||||
The true purpose of Yo is to provide a great experience on any platform for
|
|
||||||
anyone. It should be easy to use and understand making it a great option for
|
|
||||||
people coming from other social networks to engage in their community.
|
|
||||||
|
|
||||||
Yo comes from the legacy Damus Web app an holds all of its history. It has been
|
|
||||||
rewritten to accomodate for the scale issues that we have seen so that it can
|
|
||||||
continue to be used. The main reason for branching off is due to the lack of
|
|
||||||
parity between Damus iOS (and new codebase improvements) and that of what the
|
|
||||||
web version would support.
|
|
||||||
|
|
||||||
New minor features will continue to be added, but nothing substancial without
|
|
||||||
full time maintainers. Security will always be a top concern.
|
|
||||||
|
|
||||||
[Issue Tracker](https://todo.sr.ht/~tomtom/damus-web-issues)
|
[Issue Tracker](https://todo.sr.ht/~tomtom/damus-web-issues)
|
||||||
|
|
||||||
## Contribution Guide
|
"Yo Sup" is a minimal Nostr client that grew out of the original Damus Web
|
||||||
|
code. It's goal is to view your feed and access your direct messages very fast.
|
||||||
|
So fast it works over 3G with a fresh page load. It has no goals to fulfill any
|
||||||
|
other NIPs, please use other clients such as Snort, Coracle, or Iris.
|
||||||
|
|
||||||
There are rules to contributing to this client. Please ensure you read them
|
It's written in plain JavaScript, HTML, and CSS for ease of development and
|
||||||
before making changes and supplying patch notes.
|
building, see the example Dockerfile. Small features and optimizations will be
|
||||||
|
added as needed, but the application is considered "complete".
|
||||||
|
|
||||||
- No transpilers. All source code should work out of the box.
|
Patches are welcomed via email.
|
||||||
- Keep source code organised. Refer to the folder structure. If you have a
|
|
||||||
question, ask it.
|
|
||||||
- Do not include your personal tools in the source code. Use your own scripts
|
|
||||||
outside of the project. This does not include build tools such as Make.
|
|
||||||
- Use tabs & write JS with snake_case. End of discussion.
|
|
||||||
- Do not include binary files.
|
|
||||||
- No NPM (and kin) environments. If you need a file from an external resource
|
|
||||||
mark the location in the "sources" file and add it to the repo.
|
|
||||||
- No frameworks. Learn the browser tools and write good code.
|
|
||||||
- No experimental browser APIs.
|
|
||||||
- Do not write animations in JavaScript, CSS only. Keep them short and snappy.
|
|
||||||
Animations should not be a forefront, but an enjoyable addition.
|
|
||||||
- All new & modified code should be properly documented.
|
|
||||||
- Source code should be readable in the browser.
|
|
||||||
- Search for the TODOs.
|
|
||||||
|
|
||||||
These rules are subject to discussion.
|
|
||||||
|
|
||||||
## Terminology
|
|
||||||
|
|
||||||
* Sign Out - Not "log out", "logout", "log off", etc.
|
|
||||||
* Sign In - Not "login", "log in", "signin", "sign-in", etc.
|
|
||||||
* Share - Not "boosted", "retweeted", "repost", etc.
|
|
||||||
* Send - Not "tweet", "toot", "post", etc.
|
|
||||||
* Link - Not "share".
|
|
||||||
|
|
||||||
## Known Issues
|
|
||||||
|
|
||||||
* You cannot send events when running from an IP address that is not secure.
|
|
||||||
Work arounds are not known at this time.
|
|
||||||
|
|
||||||
|
|
|
@ -1,32 +1,29 @@
|
||||||
@media (max-width: 800px){
|
@media (max-width: 840px){
|
||||||
:root {
|
|
||||||
/* TODO font size should not be controlled by CSS:
|
|
||||||
* Instead I would prefer user settings. The main reason is the font is
|
|
||||||
* too small on my desktop when I use the app in column mode.
|
|
||||||
*/
|
|
||||||
--fsSmall: 10px;
|
|
||||||
--fsNormal: 14px;
|
|
||||||
--fsReduced: 12px;
|
|
||||||
--fsEnlarged: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Utility */
|
/* Utility */
|
||||||
.vertical-hide {
|
.vertical-hide {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Application Framework */
|
/* Application Framework */
|
||||||
#gnav {
|
|
||||||
display: initial;
|
|
||||||
}
|
|
||||||
#view {
|
#view {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: initial;
|
width: initial;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
}
|
}
|
||||||
|
.nav.mobile {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
#content header > label {
|
#content header > label {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
}
|
}
|
||||||
|
.nav.mobile .new-note {
|
||||||
|
position: fixed;
|
||||||
|
height: initial;
|
||||||
|
bottom: 88px;
|
||||||
|
right: 20px;
|
||||||
|
z-index: var(--zGlobal);
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Event */
|
/* Event */
|
||||||
.pfp { /* TODO sync up with userpic */
|
.pfp { /* TODO sync up with userpic */
|
||||||
|
|
115
css/styles.css
115
css/styles.css
|
@ -45,13 +45,6 @@ th, td {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
#gsticker {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Welcome */
|
/* Welcome */
|
||||||
|
|
||||||
#container-busy .loader {
|
#container-busy .loader {
|
||||||
|
@ -83,98 +76,53 @@ th, td {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Navigation */
|
/* Navigation */
|
||||||
#nav {
|
.nav.full {
|
||||||
border-right: 1px solid var(--clrBorder);
|
border-right: 1px solid var(--clrBorder);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
#nav > div {
|
.nav.full > div {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 16px;
|
top: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
}
|
}
|
||||||
#nav > div > * {
|
.nav.full > div > * {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
#nav > div[data-active] img.active {
|
.nav.mobile {
|
||||||
|
display: none;
|
||||||
|
background: var(--clrBg);
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: var(--zHeader);
|
||||||
|
flex-direction: row;
|
||||||
|
border-top: var(--clrBorder) 1px solid;
|
||||||
|
}
|
||||||
|
.nav.mobile button {
|
||||||
|
padding: 18px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.nav [data-view].active img.inactive,
|
||||||
|
.nav [data-view] img.active {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#nav > div[data-active="home"] [data-view="friends"] img.inactive,
|
.nav [data-view].active img.active {
|
||||||
#nav > div[data-active="explore"] [data-view="explore"] img.inactive,
|
|
||||||
#nav > div[data-active="notifications"] [data-view="notifications"] img.inactive,
|
|
||||||
#nav > div[data-active="settings"] [data-view="settings"] img.inactive,
|
|
||||||
#nav > div[data-active="messages"] [data-view="dm"] img.inactive {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#nav > div[data-active="home"] [data-view="friends"] img.active,
|
|
||||||
#nav > div[data-active="explore"] [data-view="explore"] img.active,
|
|
||||||
#nav > div[data-active="notifications"] [data-view="notifications"] img.active,
|
|
||||||
#nav > div[data-active="settings"] [data-view="settings"] img.active,
|
|
||||||
#nav > div[data-active="messages"] [data-view="dm"] img.active {
|
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
#new-note {
|
|
||||||
background: white;
|
|
||||||
height: 56px;
|
|
||||||
border-radius: 38px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app-icon-logo > img {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
}
|
|
||||||
button.nav > img.icon {
|
button.nav > img.icon {
|
||||||
width: 28px;
|
width: 28px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
}
|
}
|
||||||
#gnav {
|
.nav button.new-note {
|
||||||
display: none;
|
background: white;
|
||||||
position: fixed;
|
height: 56px;
|
||||||
bottom: 55px;
|
border-radius: 38px;
|
||||||
right: 55px;
|
|
||||||
z-index: var(--zGlobal);
|
|
||||||
}
|
}
|
||||||
#gnav button {
|
#app-icon-logo > img {
|
||||||
position: absolute;
|
width: 36px;
|
||||||
top: 0;
|
height: 36px;
|
||||||
left: 0;
|
|
||||||
font-size: 24px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--clrText);
|
|
||||||
color: var(--clrBg);
|
|
||||||
padding: 10px;
|
|
||||||
border: transparent 5px solid;
|
|
||||||
transition: top 0.05s linear;
|
|
||||||
transform: translateX(-50%) translateY(-50%);
|
|
||||||
z-index: calc(var(--zGlobal) - 1);
|
|
||||||
}
|
|
||||||
#gnav button > .icon {
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
}
|
|
||||||
#gnav button[action="toggle-gnav"] {
|
|
||||||
z-index: var(--zGlobal);
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
#gnav.open button[data-view="friends"] {
|
|
||||||
top: -375px;
|
|
||||||
}
|
|
||||||
#gnav.open button[data-view="explore"] {
|
|
||||||
top: -300px;
|
|
||||||
}
|
|
||||||
#gnav.open button[data-view="dm"] {
|
|
||||||
top: -225px;
|
|
||||||
}
|
|
||||||
#gnav.open button[data-view="notifications"] {
|
|
||||||
top: -150px;
|
|
||||||
}
|
|
||||||
#gnav.open button[data-view="notifications"] .new-notifications {
|
|
||||||
right: 9px;
|
|
||||||
}
|
|
||||||
#gnav.open button[data-view="settings"] {
|
|
||||||
top: -75px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.new-notifications {
|
.new-notifications {
|
||||||
|
@ -195,24 +143,29 @@ button.nav > img.icon {
|
||||||
flex-flow: row;
|
flex-flow: row;
|
||||||
}
|
}
|
||||||
#view {
|
#view {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
border-right: 1px solid var(--clrBorder);
|
border-right: 1px solid var(--clrBorder);
|
||||||
width: 750px;
|
width: 750px;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
#view > div > header {
|
#view > header {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: var(--zHeader);
|
z-index: var(--zHeader);
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
-webkit-backdrop-filter: blur(20px);
|
-webkit-backdrop-filter: blur(20px);
|
||||||
}
|
}
|
||||||
#view > div > header > label {
|
#view > header > label {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
#timeline, #settings, #dms {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
#header-tools {
|
#header-tools {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -551,7 +504,7 @@ code {
|
||||||
}
|
}
|
||||||
#settings header > label {
|
#settings header > label {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: var(--fsEnlarged);
|
font-size: var(--fsLarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Messaging */
|
/* Messaging */
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
--fsReduced: 14px;
|
--fsReduced: 14px;
|
||||||
--fsNormal: 16px;
|
--fsNormal: 16px;
|
||||||
--fsEnlarged: 18px;
|
--fsEnlarged: 18px;
|
||||||
|
--fsLarge: 22px;
|
||||||
|
|
||||||
/* Font Families */
|
/* Font Families */
|
||||||
--ffDefault: "Noto Sans", sans-serif;
|
--ffDefault: "Noto Sans", sans-serif;
|
||||||
|
|
99
index.html
99
index.html
|
@ -44,39 +44,18 @@
|
||||||
Yo, Sup?
|
Yo, Sup?
|
||||||
<img class="icon svg" src="/icon/logo-inverted.svg"/>
|
<img class="icon svg" src="/icon/logo-inverted.svg"/>
|
||||||
</h1>
|
</h1>
|
||||||
<p>The blue bird experience for Nostr.</p>
|
<p>A minimal experience for Nostr.</p>
|
||||||
<button class="action" action="sign-in">
|
<p>Please access with a nos2x compatible browser.</p>
|
||||||
Sign In with Key
|
|
||||||
<img src="/icon/key.svg" class="icon svg small invert"/>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="container-app" class="hide">
|
<div id="container-app" class="hide">
|
||||||
<nav id="gnav">
|
|
||||||
<button class="icon" action="toggle-gnav" title="Open Menu">
|
|
||||||
<img class="icon svg invert" src="/icon/logo.svg"/>
|
|
||||||
</button>
|
|
||||||
<button class="icon" action="open-view" data-view="friends" title="Home">
|
|
||||||
<img class="icon svg invert" src="/icon/home.svg"/>
|
|
||||||
</button>
|
|
||||||
<button class="icon" action="open-view" data-view="dm" title="Direct Messages">
|
|
||||||
<img class="icon svg invert" src="/icon/messages.svg"/>
|
|
||||||
<div class="new-notifications hide" role="dm"></div>
|
|
||||||
</button>
|
|
||||||
<button class="icon" action="open-view" data-view="notifications" title="Notifications">
|
|
||||||
<img class="icon svg invert" src="/icon/notifications.svg"/>
|
|
||||||
<div class="new-notifications hide" role="activity"></div>
|
|
||||||
</button>
|
|
||||||
<button class="icon" action="open-view" data-view="settings" title="Settings">
|
|
||||||
<img class="icon svg invert" src="/icon/settings.svg"/>
|
|
||||||
</button>
|
|
||||||
</nav>
|
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div class="flex-fill vertical-hide"></div>
|
<div class="flex-fill vertical-hide"></div>
|
||||||
<div id="nav" class="flex-noshrink vertical-hide">
|
<nav id="nav" class="nav full flex-noshrink vertical-hide">
|
||||||
<div data-active="home">
|
<div>
|
||||||
<div id="app-icon-logo">
|
<div id="app-icon-logo">
|
||||||
<img class="icon svg" title="Damus" src="/icon/logo-inverted.svg"/>
|
<img class="icon svg" title="Damus" src="/icon/logo-inverted.svg"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -102,18 +81,17 @@
|
||||||
<img class="icon svg inactive" src="/icon/settings.svg"/>
|
<img class="icon svg inactive" src="/icon/settings.svg"/>
|
||||||
<img class="icon svg active" src="/icon/settings-active.svg"/>
|
<img class="icon svg active" src="/icon/settings-active.svg"/>
|
||||||
</button>
|
</button>
|
||||||
<button id="new-note" action="new-note" title="New Note" class="nav icon">
|
<button action="new-note" title="New Note" class="nav icon new-note">
|
||||||
<img class="icon svg invert" src="/icon/new-note.svg"/>
|
<img class="icon svg invert" src="/icon/new-note.svg"/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</nav>
|
||||||
|
|
||||||
<div id="view">
|
<div id="view">
|
||||||
<div>
|
|
||||||
<header>
|
<header>
|
||||||
<label>Home</label>
|
<label>Home</label>
|
||||||
<div id="header-tools">
|
<div id="header-tools">
|
||||||
<button class="action small bordered hide"
|
<button class="action small hide"
|
||||||
disabled action="mark-all-read">
|
disabled action="mark-all-read">
|
||||||
Mark All Read
|
Mark All Read
|
||||||
</button>
|
</button>
|
||||||
|
@ -167,11 +145,6 @@
|
||||||
<button action="show-timeline-new">
|
<button action="show-timeline-new">
|
||||||
Show New (<span role="count">0</span>)</button>
|
Show New (<span role="count">0</span>)</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="dms-not-available" class="hide">
|
|
||||||
DMs could not be decrypted due to lack of nip04
|
|
||||||
integration. Please use an extension such as nos2x or
|
|
||||||
Alby.
|
|
||||||
</div>
|
|
||||||
<div id="dms" class="hide">
|
<div id="dms" class="hide">
|
||||||
</div>
|
</div>
|
||||||
<div id="timeline" class="events"></div>
|
<div id="timeline" class="events"></div>
|
||||||
|
@ -198,35 +171,41 @@
|
||||||
</table>
|
</table>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<header><label>About</label></header>
|
<header><label>Info</label></header>
|
||||||
<p>
|
<p>
|
||||||
Yo, Sup? was originally Damus Web
|
<a href="https://git.sr.ht/~tomtom/damus">Source Code</a>
|
||||||
written by <span action="open-profile" class="username clickable"
|
<a href="https://todo.sr.ht/~tomtom/damus-web-issues">Bug Tracker</a>
|
||||||
data-pubkey="32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245">
|
<a href="mailto:thomas.c.mathews@gmail.com">Email Me</a>
|
||||||
jb55</span>. It was rewritten by in order to bring
|
|
||||||
it up to date.
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
|
||||||
Yo is open source under the AGPL-3 license. You can
|
|
||||||
find the source code <a
|
|
||||||
href="https://git.sr.ht/~tomtom/damus">here</a>.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Bugs and feature requests can be emailed to <a
|
|
||||||
href="mailto:thomas.c.mathews@gmail.com">thomas.c.mathews@gmail.com</a>
|
|
||||||
or submitted to the <a
|
|
||||||
href="https://todo.sr.ht/~tomtom/damus-web-issues">
|
|
||||||
tracker</a>.
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<button class="action" role="sign-out">
|
|
||||||
Sign Out
|
|
||||||
<img class="icon svg small invert" src="/icon/sign-out.svg"/>
|
|
||||||
</button>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<nav class="nav mobile">
|
||||||
|
<button action="open-view" data-view="friends" class="icon"
|
||||||
|
title="Home">
|
||||||
|
<img class="icon svg inactive" src="/icon/home.svg"/>
|
||||||
|
<img class="icon svg active" src="/icon/home-active.svg"/>
|
||||||
|
</button>
|
||||||
|
<button action="open-view" data-view="dm" class="icon"
|
||||||
|
title="Direct Messages">
|
||||||
|
<img class="icon svg inactive" src="/icon/messages.svg"/>
|
||||||
|
<img class="icon svg active" src="/icon/messages-active.svg"/>
|
||||||
|
<div class="new-notifications hide" role="dm"></div>
|
||||||
|
</button>
|
||||||
|
<button action="open-view" data-view="notifications"
|
||||||
|
class="icon" title="Notifications">
|
||||||
|
<img class="icon svg inactive" src="/icon/notifications.svg"/>
|
||||||
|
<img class="icon svg active" src="/icon/notifications-active.svg"/>
|
||||||
|
<div class="new-notifications hide" role="activity"></div>
|
||||||
|
</button>
|
||||||
|
<button action="open-view" data-view="settings"
|
||||||
|
title="Settings" class="icon">
|
||||||
|
<img class="icon svg inactive" src="/icon/settings.svg"/>
|
||||||
|
<img class="icon svg active" src="/icon/settings-active.svg"/>
|
||||||
|
</button>
|
||||||
|
<button action="new-note" title="New Note" class="nav icon new-note">
|
||||||
|
<img class="icon svg invert" src="/icon/new-note.svg"/>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-fill vertical-hide"></div>
|
<div class="flex-fill vertical-hide"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
18
js/main.js
18
js/main.js
|
@ -81,10 +81,6 @@ async function webapp_init() {
|
||||||
|
|
||||||
// Load data from storage
|
// Load data from storage
|
||||||
await model_load_settings(model);
|
await model_load_settings(model);
|
||||||
/*err = await contacts_load(model);
|
|
||||||
if (err) {
|
|
||||||
window.alert("Unable to load contacts.");
|
|
||||||
}*/
|
|
||||||
init_settings(model);
|
init_settings(model);
|
||||||
|
|
||||||
// Create our pool so that event processing functions can work
|
// Create our pool so that event processing functions can work
|
||||||
|
@ -96,14 +92,6 @@ async function webapp_init() {
|
||||||
pool.on("eose", on_pool_eose);
|
pool.on("eose", on_pool_eose);
|
||||||
pool.on("ok", on_pool_ok);
|
pool.on("ok", on_pool_ok);
|
||||||
|
|
||||||
// Load all events from storage and re-process them so that apply correct
|
|
||||||
// effects.
|
|
||||||
/*await model_load_events(model, (ev)=> {
|
|
||||||
model_process_event(model, undefined, ev);
|
|
||||||
});
|
|
||||||
log_debug("loaded events", Object.keys(model.all_events).length);
|
|
||||||
*/
|
|
||||||
|
|
||||||
var { mode, opts, valid } = parse_url_mode();
|
var { mode, opts, valid } = parse_url_mode();
|
||||||
view_timeline_apply_mode(model, mode, opts, !valid);
|
view_timeline_apply_mode(model, mode, opts, !valid);
|
||||||
on_timer_timestamps();
|
on_timer_timestamps();
|
||||||
|
@ -171,7 +159,7 @@ function on_timer_save() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const model = DAMUS;
|
const model = DAMUS;
|
||||||
//model_save_events(model);
|
//model_save_events(model);
|
||||||
model_save_settings(model);
|
//model_save_settings(model);
|
||||||
on_timer_save();
|
on_timer_save();
|
||||||
}, 1 * 1000);
|
}, 1 * 1000);
|
||||||
}
|
}
|
||||||
|
@ -300,6 +288,7 @@ function fetch_profile(pubkey, pool, relay) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetch_thread_history(evid, pool) {
|
function fetch_thread_history(evid, pool) {
|
||||||
|
// TODO look up referenced relays for thread history
|
||||||
const sid = `${SID_THREAD}:${evid}`
|
const sid = `${SID_THREAD}:${evid}`
|
||||||
pool.subscribe(sid, [{
|
pool.subscribe(sid, [{
|
||||||
kinds: PUBLIC_KINDS,
|
kinds: PUBLIC_KINDS,
|
||||||
|
@ -309,8 +298,7 @@ function fetch_thread_history(evid, pool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetch_friends_history(friends, pool, relay) {
|
function fetch_friends_history(friends, pool, relay) {
|
||||||
// TODO only fetch friends history from their desired relay instead of
|
// TODO fetch history of each friend by their desired relay
|
||||||
// pinging all of the relays
|
|
||||||
pool.subscribe(SID_FRIENDS, [{
|
pool.subscribe(SID_FRIENDS, [{
|
||||||
kinds: PUBLIC_KINDS,
|
kinds: PUBLIC_KINDS,
|
||||||
authors: friends,
|
authors: friends,
|
||||||
|
|
|
@ -1,21 +1,12 @@
|
||||||
function init_settings(model) {
|
function init_settings(model) {
|
||||||
const el = find_node("#settings");
|
const el = find_node("#settings");
|
||||||
find_node("#add-relay", el).addEventListener("click", on_click_add_relay);
|
find_node("#add-relay", el).addEventListener("click", on_click_add_relay);
|
||||||
find_node("[role='sign-out']", el).addEventListener("click", on_click_sign_out);
|
|
||||||
const rlist = find_node("#relay-list tbody", el);
|
const rlist = find_node("#relay-list tbody", el);
|
||||||
model.relays.forEach((str) => {
|
model.relays.forEach((str) => {
|
||||||
rlist.appendChild(new_relay_item(str));
|
rlist.appendChild(new_relay_item(str));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function on_click_sign_out(ev) {
|
|
||||||
if (confirm("Are you sure you want to sign out?")) {
|
|
||||||
localStorage.clear();
|
|
||||||
await dbclear();
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function new_relay_item(str) {
|
function new_relay_item(str) {
|
||||||
const tr = document.createElement('tr');
|
const tr = document.createElement('tr');
|
||||||
tr.innerHTML = `<td>${str}</td>
|
tr.innerHTML = `<td>${str}</td>
|
||||||
|
|
|
@ -116,16 +116,13 @@ function view_timeline_apply_mode(model, mode, opts={}, push_state=true) {
|
||||||
// Do some visual updates
|
// Do some visual updates
|
||||||
find_node("#show-more").classList.add("hide");
|
find_node("#show-more").classList.add("hide");
|
||||||
find_node("#view header > label").innerText = name;
|
find_node("#view header > label").innerText = name;
|
||||||
find_node("#nav > div[data-active]").dataset.active = names[mode].toLowerCase();
|
view_update_navs(mode);
|
||||||
find_node("#view [role='profile-info']").classList.toggle("hide", mode != VM_USER);
|
find_node("#view [role='profile-info']").classList.toggle("hide", mode != VM_USER);
|
||||||
const timeline_el = find_node("#timeline");
|
const timeline_el = find_node("#timeline");
|
||||||
timeline_el.classList.toggle("reverse", mode == VM_THREAD);
|
timeline_el.classList.toggle("reverse", mode == VM_THREAD);
|
||||||
timeline_el.classList.toggle("hide", mode == VM_SETTINGS || mode == VM_DM);
|
timeline_el.classList.toggle("hide", mode == VM_SETTINGS || mode == VM_DM);
|
||||||
find_node("#settings").classList.toggle("hide", mode != VM_SETTINGS);
|
find_node("#settings").classList.toggle("hide", mode != VM_SETTINGS);
|
||||||
find_node("#dms").classList.toggle("hide", mode != VM_DM);
|
find_node("#dms").classList.toggle("hide", mode != VM_DM);
|
||||||
find_node("#dms-not-available")
|
|
||||||
.classList.toggle("hide", mode == VM_DM_THREAD || mode == VM_DM ?
|
|
||||||
dms_available() : true);
|
|
||||||
find_node("#header-tools button[action='mark-all-read']")
|
find_node("#header-tools button[action='mark-all-read']")
|
||||||
.classList.toggle("hide", mode != VM_DM);
|
.classList.toggle("hide", mode != VM_DM);
|
||||||
|
|
||||||
|
@ -220,6 +217,12 @@ function view_timeline_refresh(model, mode, opts={}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function view_update_navs(mode) {
|
||||||
|
find_nodes("nav.nav button[data-view]").forEach((el)=> {
|
||||||
|
el.classList.toggle("active", el.dataset.view == mode)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function view_show_spinner(show=true) {
|
function view_show_spinner(show=true) {
|
||||||
find_node("#view .loading-events").classList.toggle("hide", !show);
|
find_node("#view .loading-events").classList.toggle("hide", !show);
|
||||||
}
|
}
|
||||||
|
@ -546,7 +549,6 @@ function get_thread_root_id(damus, id) {
|
||||||
|
|
||||||
function switch_view(mode, opts) {
|
function switch_view(mode, opts) {
|
||||||
view_timeline_apply_mode(DAMUS, mode, opts);
|
view_timeline_apply_mode(DAMUS, mode, opts);
|
||||||
close_gnav();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle_hide_replys(el) {
|
function toggle_hide_replys(el) {
|
||||||
|
@ -668,9 +670,6 @@ function onclick_any(ev) {
|
||||||
const el = ev.target;
|
const el = ev.target;
|
||||||
const action = el.getAttribute("action");
|
const action = el.getAttribute("action");
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "toggle-gnav":
|
|
||||||
toggle_gnav(el);
|
|
||||||
break;
|
|
||||||
case "sign-in":
|
case "sign-in":
|
||||||
signin();
|
signin();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3,17 +3,6 @@
|
||||||
* this file grows specific UI area code should be migrated to its own file.
|
* this file grows specific UI area code should be migrated to its own file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* toggle_gnav hides or shows the global navigation's additional buttons based
|
|
||||||
* on its opened state.
|
|
||||||
*/
|
|
||||||
function toggle_gnav(el) {
|
|
||||||
el.parentElement.classList.toggle("open");
|
|
||||||
}
|
|
||||||
|
|
||||||
function close_gnav() {
|
|
||||||
find_node("#gnav").classList.remove("open");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* init_message_textareas finds all message textareas and updates their initial
|
/* init_message_textareas finds all message textareas and updates their initial
|
||||||
* height based on their content (0). This is so there is no jaring affect when
|
* height based on their content (0). This is so there is no jaring affect when
|
||||||
* the page loads.
|
* the page loads.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue