Compare commits

..

7 commits

9 changed files with 167 additions and 38 deletions

View file

@ -1,6 +1,7 @@
# underBBS
underBBS is a platform-agnostic messaging and social media client
underBBS is a platform-agnostic messaging and social media client (feat consultation and motivational support from
miggymofongo!!!)
## design

View file

@ -216,7 +216,6 @@ func (self *MisskeyAdapter) toMessage(n mkm.Note, bustCache bool) *Message {
ReplyTo: n.ReplyID,
ReplyCount: int(n.RepliesCount),
Replies: []string{},
RenoteId: (*string)(n.RenoteID),
}
for _, f := range n.Files {

View file

@ -24,7 +24,6 @@ export class AdapterElement extends HTMLElement {
// TODO: use visibility of the thread to organize into DMs and public threads
private _threads: MessageThread[] = [];
private _orphans: Message[] = [];
private _boosts: Message[] = [];
constructor() {
super();
@ -103,7 +102,6 @@ export class AdapterElement extends HTMLElement {
tse.setAttribute("data-author", this._latest);
}
}
// also update any boosts by this author
case "thread":
case "profile":
break;
@ -115,7 +113,7 @@ export class AdapterElement extends HTMLElement {
}
setIdxView() {
this.innerHTML = "<ul id='boost_carousel'></ul><ul id='dm_list'></ul><ul id='public_list'></ul>"
this.innerHTML = "<ul id='dm_list'></ul><ul id='public_list'></ul>"
}
setThreadView() {
@ -134,8 +132,6 @@ export class AdapterElement extends HTMLElement {
}
populateIdxView() {
// populate boost carousel
// skip dm list for now
// public/unified list
const pl = util.$("public_list");
@ -153,12 +149,11 @@ export class AdapterElement extends HTMLElement {
const existingThread = document.querySelector(threadSelector);
const thread = this._threads.find(t=>t.root.data.id == rootId);
if (existingThread && thread) {
debugger;
existingThread.setAttribute("data-latest", `${thread.latest}`);
existingThread.setAttribute("data-len", `${thread.messageCount}`);
existingThread.setAttribute("data-new", "true");
} else {
// if latest is a boost, put it in the carousel
// unified/public list for now
const pl = util.$("public_list");
if (pl && thread) {
@ -195,14 +190,14 @@ export class AdapterElement extends HTMLElement {
return;
}
// make multiple passes over the store until every message is either
// placed in a thread, the boost carousel, or orphaned and waiting for its parent to be returned
// placed in a thread, or orphaned and waiting for its parent to be returned
do{
for (let k of datastore.messages.keys()) {
this.placeMsg(k);
}
} while (this._threads.reduce((sum: number, thread: MessageThread)=>{
return sum + thread.messageCount;
}, 0) + this._boosts.length + this._orphans.length < datastore.messages.size);
}, 0) + this._orphans.length < datastore.messages.size);
}
placeMsg(k: string): string | null {
@ -216,20 +211,11 @@ export class AdapterElement extends HTMLElement {
util.errMsg(`message [${this._name}:${k}] doesn't exist`);
return null;
}
if (msg.renoteId) {
// fetch the referent thread and put the boost in the carousel
this._convoyBatchTimer.queue(msg.renoteId, 2000);
if (!this._boosts.some(m=>m.id == msg.id)) {
this._boosts.push(msg);
}
return null;
}
for (let t of this._threads) {
// avoid processing nodes again on subsequent passes
if (!msg || t.findNode(t.root, msg.id)) {
return null;
}
if (msg.replyTo) {
let x = t.addReply(msg.replyTo, msg);
if (x) {

View file

@ -1,14 +0,0 @@
export class BoostTileElement extends HTMLElement {
static observedAttributes = [ "data-boostid", "data-msgid", "data-author", "data-booster" ];
constructor() {
this.innerHTML = "<div class='boost_booster'></div><div class='boost_author'></div><div class='boost_content'></div>";
}
connectedCallback() {
}
attributeChangedCallback(attr: string, prev: string, next: string) {
}
}

View file

@ -12,7 +12,6 @@ export class Message {
public created: number = 0;
public edited: number | null = null;
public visibility: string = "public";
public renoteId: string | null = null;
}
export class Author {

View file

@ -0,0 +1,14 @@
export class ProfileView extends HTMLElement {
constructor() {
super();
}
const prof_view = document.createElement("span");
prof_view.setAttribute("class", "wrapper")
connectedCallback() {
this.
}
}

144
frontend/ts/profile.js Normal file
View file

@ -0,0 +1,144 @@
/* WEPA this is miggymofongo's contribution to underBBS! I'm practicing web components
in this bishhh
this template contains the html code of the side bar
*/
const template = document.createElement("template")
template.innerHTML = `
<style>
/* side profile view menu */
.sidenav {
height: 50%;
width: 0;
position: fixed; /* Stay in place */
z-index: 1;
top: 0;
left: 0;
background-color: #888;
overflow-x: hidden; /* Disable horizontal scroll */
padding-top: 60px; /* Place content 60px from the top */
transition: width 0.5s ease; /* smooth transition */
}
/*nav menu links */
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s;
}
/* change their color when you hover the mouse */
.sidenav a:hover {
color: #f1f1f1;
}
/* style the close button (puts in the top right corner) */
.sidenav .closeBtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
/* Style page content - use this if you want to push the page content to the right when you open the side navigation */
#main {
transition: margin-left .5s ease;
padding: 20px;
}
/* change the style of the sidenav on smaller screens where height is less than 450px,
(less padding and a smaller font size) */
@media screen and (max-height: 450px) {
.sidenav {padding-top: 15px;}
.sidenav a {font-size: 18px;}
}
/* the div block has an id and class so that its targeted by the styles
and the component underneath */
</style>
<div id="mySidenav" class="sidenav">
<div id="profile">
<img src="Kaido.png" alt="profile pic" style="width:100px;height100px"/>
<button href="" class="closeBtn">&times;</button>
<a href=""><button>Message</button></a>
</div>
</div>
<button id="openBtn">open profile view</button>
`
/* setting up a web component will extend the set of available HTML elements for you to use in your
project and keep your codebase organized and modular. Set up a web component in a separate file
and link it directly in your html document head.
creating a custom web component is just like creating a class. after setting up
the constructor function, you need to create some methods that tell the browser more about it.
you can add whatever methods you want, but they at least need some of the following:
1) connectedCallback() => call this method when the element is added to the document,
2) disconnectedCallback() => call this method when the element is removed from the document
3) static get observedAttributes() => this returns an array of attribute names to track for changes
4) attributeChangedCallback(name, oldValue, newValue) => this one is called when one of the attributes
5) adoptedCallback() => called when the element is moved to a new document
*/
class ProfileSideBar extends HTMLElement {
//
constructor() { // the constructor function initiates the new side bar
super()
this.appendChild(template.content.cloneNode(true))
this.sidenav = this.querySelector("#mySidenav");
this.openBtn = this.querySelector("#openBtn");
this.closeBtn = this.querySelector(".closeBtn");
this.mainContent = document.getElementById("main");
}
/* this method adds event listeners to the openBtn and closeBtn classes that
call the openNav closeNav function to open and close the sidebar*/
connectedCallback() {
this.openBtn.addEventListener("click", this.openNav.bind(this));
this.closeBtn.addEventListener("click", this.closeNav.bind(this));
}
disconnectedCallback() {
this.openBtn.removeEventListener("click", this.openNav.bind(this));
this.closeBtn.removeEventListener("click", this.closeNav.bind(this));
}
/* these two methods will open and close the profile side menu*/
openNav() {
this.sidenav.style.width = "450px"; // changes sidenav width from 0px to 450px
if (this.mainContent) {
this.mainContent.style.marginLeft = "250px";
}
}
closeNav() {
this.sidenav.style.width = "0"; //changes sidenav's width back to 0px
if (this.mainContent) {
this.mainContent.style.marginLeft = "0px"
}
}
}
/*lastly, we need to define the element tag itself and attach it to the webcomponent */
customElements.define("profile-side-bar", ProfileSideBar)

View file

@ -58,12 +58,13 @@ export class DatagramSocket {
}
static connect(): void {
const wsProto = location.protocol == "https:" ? "wss" : "ws";
const _conn = new WebSocket(`${wsProto}://${location.host}/subscribe`, "underbbs");
_conn.addEventListener("open", DatagramSocket.onOpen);
_conn.addEventListener("message", DatagramSocket.onMsg);
_conn.addEventListener("error", (e: any) => {
console.log("websocket connection error");
console.log(JSON.stringify(e));

View file

@ -25,7 +25,6 @@ type Message struct {
ReplyCount int `json:"replyCount"`
Mentions []string `json:"mentions"`
Visibility string `json:"visibility"`
RenoteId *string `json:"renoteId,omitempty"`
}
type Author struct {