Setup basic client

main
~erin 2022-06-01 13:36:14 -04:00
commit 00468d6daf
Signed by: erin
GPG Key ID: DA70E064A8C70F44
10 changed files with 4103 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

2126
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

12
Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "golgi-test"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
async-std = "1.10.0"
futures = "0.3.21"
golgi = "0.1"
rocket = { version = "0.5.0-rc.2", features = ["json"] }

87
src/main.rs Normal file
View File

@ -0,0 +1,87 @@
#[macro_use]
extern crate rocket;
use std::sync::Mutex;
use golgi::{
api::get_subset::{SubsetQuery, SubsetQueryOptions},
messages::SsbMessageContent,
GolgiError, Sbot,
};
use rocket::form::Form;
use rocket::fs::FileServer;
use rocket::serde::{json::Json, Serialize};
use rocket::State;
#[derive(FromForm)]
struct ProfileUpdate<'r> {
r#username: &'r str,
r#description: &'r str,
}
#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
struct Whoami {
username: String,
description: String,
pubkey: String,
}
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
#[post("/update", data = "<profileupdate>")]
async fn profile_update(profileupdate: Form<ProfileUpdate<'_>>) -> String {
// Initialize SSB data
let mut sbot_client = Sbot::init(None, None).await.unwrap();
let name_msg_reference = sbot_client
.publish_name(profileupdate.username)
.await
.unwrap();
let description_msg_reference = sbot_client
.publish_description(profileupdate.description)
.await
.unwrap();
return "Profile Updated!".to_string();
}
#[get("/whoami")]
async fn whoami() -> Json<Whoami> {
// Initialize SSB data
let mut sbot_client = Sbot::init(None, None).await.unwrap();
let id = sbot_client.whoami().await.unwrap();
let profile_info = sbot_client.get_profile_info(&id).await.unwrap();
let name = match profile_info.get("name") {
Some(s) => s,
None => {
println!("Could not get name");
""
}
};
let description = match profile_info.get("description") {
Some(s) => s,
None => {
println!("Could not get description");
""
}
};
Json(Whoami {
username: name.to_string(),
description: description.to_string(),
pubkey: id,
})
}
#[rocket::main]
async fn main() {
let result = rocket::build()
.mount("/api", routes![index, whoami, profile_update])
.mount("/", FileServer::from("static/"))
.launch()
.await;
}

26
static/about/index.html Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/style.css">
<title>WebButt | About</title>
</head>
<body>
<nav>
<ul>
<li><a href="/profile">Profile</a></li>
<li><a href="/feed">Home Feed</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
<h1>WebButt</h1>
<p>WebButt is a tiny application for me to play around and test writing an SSB client.</p>
<p>The backend is written in Rust, and uses the <a href="http://golgi.mycelial.technology/">golgi</a> client to interface with a backend server.<p>
<p>It is currently only tested with the <a href="https://github.com/cryptoscope/ssb">go-ssb</a> server.</p>
<p><i>Written by Erin Nova</i></p>
</body>
</html>

37
static/index.html Normal file
View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/style.css">
<title>WebButt</title>
</head>
<body>
<nav>
<ul>
<li><a href="/profile">Profile</a></li>
<li><a href="/feed">Home Feed</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
<h1>WebButt</h1>
<p>A small test SSB application written in Rust and Javascript</p>
<div id="profile">
<h2 id="username"></h2>
<p id="description"></p>
<code id="pubkey"></code>
</div>
<script src="zepto.js"></script>
<script>
import { whoami } from '/ssb.js';
whoami();
</script>
<noscript>
<p>Sorry, but this app requires JS to function :/</p>
</noscript>
</body>
</html>

48
static/profile/index.html Normal file
View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/style.css">
<title>WebButt | Profile</title>
</head>
<body>
<nav>
<ul>
<li><a href="/profile">Profile</a></li>
<li><a href="/feed">Home Feed</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
<div id="profile">
<h1 id="profile_username"></h2>
<code id="profile_pubkey"></code>
<div class="markdown" id="profile_description"></div>
</div>
<hr>
<form id="profileForm" class="form">
<div class="form">
<label for="username">New Username: </label>
<input type="text" name="username" id="form_username"></input>
</div>
<div class="form">
<label for="description">New Description: </label>
<textarea name="description" id="form_description" cols="45" rows="15"></textarea>
</div>
<div class="form">
<input type="submit" value="Update">
</div>
</form>
<script src="zepto.js"></script>
<script type="text/javascript" src="//simonwaldherr.github.io/micromarkdown.js/dist/micromarkdown.min.js"></script>
<script src="ssb.js"></script>
<noscript>
<p>Sorry, but this app requires JS to function :/</p>
</noscript>
</body>
</html>

49
static/ssb.js Normal file
View File

@ -0,0 +1,49 @@
function whoami() {
$.get("/api/whoami", function(response){
$("#profile_username").text(response.username)
$('#form_username').attr('value', response.username)
$("#profile_description").html(micromarkdown.parse(response.description))
$('#form_description').text(response.description)
$("#profile_pubkey").text(response.pubkey)
})
}
whoami()
window.addEventListener( "load", function () {
function sendData() {
const XHR = new XMLHttpRequest();
// Bind the FormData object and the form element
const FD = new FormData( form );
// Define what happens on successful data submission
XHR.addEventListener( "load", function(event) {
alert( event.target.responseText );
} );
// Define what happens in case of error
XHR.addEventListener( "error", function( event ) {
alert( 'Oops! Something went wrong.' );
} );
// Set up our request
XHR.open( "POST", "/api/update" );
// The data sent is what the user provided in the form
XHR.send( FD );
}
// Access the form element...
const form = document.getElementById( "profileForm" );
// ...and take over its submit event.
form.addEventListener( "submit", function ( event ) {
event.preventDefault();
sendData();
whoami();
} );
} );

67
static/style.css Normal file
View File

@ -0,0 +1,67 @@
body {
margin: 40px auto;
max-width: 650px;
line-height: 1.6;
font-size: 18px;
color: #444;
background-color: #EEEEEE;
padding: 0 10px;
}
h1, h2, h3, {
line-height: 1.2;
}
#username {
margin-bottom: 0;
}
nav ul {
padding-left: 0;
}
nav ul li {
list-style: none;
display: inline;
margin: auto;
text-decoration: none;
padding-right: 25px;
}
a {
color: #85A1F2;
}
a:visited {
color: #A38DC9;
}
form.form {
display: table;
}
div.form {
display: table-row;
}
label, input, textarea {
display: table-cell;
margin-bottom: 10px;
}
label {
padding-right: 10px;
}
#profile .markdown {
padding: 15px;
font-size: 14px;
line-height: 1.2;
margin: 0;
}
#profile .markdown h1, #profile .markdown h2, #profile .markdown h3 {
margin-bottom: 0px;
margin-top: 0px;
padding-top: 5px;
}

1650
static/zepto.js Normal file

File diff suppressed because it is too large Load Diff