Merge branch 'master' of github.com:fraction/oasis into conn-buttons

This commit is contained in:
Christian Bundy 2020-01-28 10:25:42 -08:00
commit ec3e4d489a
14 changed files with 118 additions and 116 deletions

View File

@ -38,7 +38,7 @@ Want more? Check out [`install.md`](https://github.com/fraction/oasis/blob/maste
## Resources
- [Contributing](https://github.com/fraction/oasis/blob/master/docs/contributing.md)
- [Architecture](https://github.com/fraction/oasis/blob/master/docs/architecture.md)
- [Help](https://github.com/fraction/oasis/issues/new/choose)
- [Roadmap](https://github.com/fraction/oasis/blob/master/docs/roadmap.md)
- [Security Policy](https://github.com/fraction/oasis/blob/master/docs/security.md)

83
package-lock.json generated
View File

@ -36,26 +36,6 @@
"source-map": "^0.5.0"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@ -159,28 +139,6 @@
"@babel/code-frame": "^7.8.3",
"@babel/parser": "^7.8.3",
"@babel/types": "^7.8.3"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
}
}
},
"@babel/traverse": {
@ -200,26 +158,6 @@
"lodash": "^4.17.13"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
"dev": true,
"requires": {
"@babel/highlight": "^7.8.3"
}
},
"@babel/highlight": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
@ -274,6 +212,19 @@
"ssb-tangle": "^1.0.1",
"ssb-unix-socket": "^1.0.0",
"ssb-ws": "^6.2.3"
},
"dependencies": {
"ssb-tangle": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ssb-tangle/-/ssb-tangle-1.0.1.tgz",
"integrity": "sha512-Miu42xjISxwQGX1J59VC1FgMmLQShILZeYXOhCL5aavoYm7nzeykrEM//pU55pVlUTAbXLttvhH56IDXTPX/Kw==",
"requires": {
"is-my-json-valid": "^2.20.0",
"pull-stream": "^3.6.11",
"ssb-ref": "^2.13.9",
"ssb-sort": "^1.1.3"
}
}
}
},
"@nodelib/fs.scandir": {
@ -985,7 +936,6 @@
"requires": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
"fsevents": "~2.1.2",
"glob-parent": "~5.1.0",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
@ -2915,13 +2865,6 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
"integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
"dev": true,
"optional": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",

View File

@ -45,6 +45,7 @@
"ssb-mentions": "^0.5.0",
"ssb-msgs": "^5.2.0",
"ssb-ref": "^2.13.9",
"ssb-tangle": "^1.0.1",
"ssb-thread-schema": "^1.1.1",
"yargs": "^15.0.0"
},

View File

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<title>oasis favicon</title>
<text x="0" y="15">🏝️</text>
<text x="0" y="14">🏝️</text>
</svg>

Before

Width:  |  Height:  |  Size: 139 B

After

Width:  |  Height:  |  Size: 139 B

View File

@ -46,6 +46,7 @@
--common-radius: var(--micro);
--measure: calc(var(--peta) + var(--mega));
--line: 1.5rem;
--code-size: 85%;
}
* {
@ -67,6 +68,7 @@ html {
line-height: 1.5;
margin: 0;
padding: 0;
overflow-y: scroll;
}
main {
@ -194,7 +196,7 @@ section code {
overflow-wrap: break-word;
padding: 0.125em 0.25em;
margin: 0;
font-size: 85%;
font-size: var(--code-size);
background-color: var(--bg);
border-radius: var(--common-radius);
border: var(--pico) solid var(--bg-status);
@ -315,6 +317,8 @@ section {
margin: var(--whole) 0;
word-wrap: break-word;
background: var(--bg);
width: 100%;
box-sizing: border-box;
}
section > header {
@ -462,3 +466,26 @@ hr {
justify-content: space-between;
margin: var(--whole) 0;
}
/* sidebar only appears on big screens */
@media (min-width: calc(45rem)) {
body > nav > ul {
justify-content: right;
flex-direction: column;
margin-right: var(--kilo);
position: sticky;
top: var(--whole);
}
body > nav > ul > li {
margin-bottom: var(--whole);
}
main {
width: 100%;
max-width: var(--measure);
}
body {
display: flex;
justify-content: center;
max-width: none;
}
}

View File

@ -3,6 +3,9 @@ const koaStatic = require("koa-static");
const path = require("path");
const mount = require("koa-mount");
/**
* @param {{ host: string, port: number, routes: any }} input
*/
module.exports = ({ host, port, routes }) => {
const assets = new Koa();
assets.use(koaStatic(path.join(__dirname, "assets")));
@ -10,10 +13,10 @@ module.exports = ({ host, port, routes }) => {
const app = new Koa();
module.exports = app;
app.on("error", e => {
app.on("error", err => {
// Output full error objects
e.message = e.stack;
e.expose = true;
err.message = err.stack;
err.expose = true;
return null;
});

View File

@ -99,15 +99,17 @@ router
const publicPopular = async ({ period }) => {
const messages = await post.popular({ period });
const option = somePeriod =>
li(
period === somePeriod
? a({ class: "current", href: `./${somePeriod}` }, somePeriod)
: a({ href: `./${somePeriod}` }, somePeriod)
const option = somePeriod => {
const lowerPeriod = somePeriod.toLowerCase();
return li(
period === lowerPeriod
? a({ class: "current", href: `./${lowerPeriod}` }, somePeriod)
: a({ href: `./${lowerPeriod}` }, somePeriod)
);
};
const prefix = nav(
ul(option("day"), option("week"), option("month"), option("year"))
ul(option("Day"), option("Week"), option("Month"), option("Year"))
);
return publicView({

View File

@ -21,6 +21,7 @@ const defaultOptions = {
meta: true
};
/** @param {object[]} customOptions */
const configure = (...customOptions) =>
Object.assign({}, defaultOptions, ...customOptions);
@ -161,14 +162,15 @@ module.exports = cooler => {
dest: feedId
});
// TODO: Refactor to stop doing awful string comparison.
if (isFollowing === true && isBlocking === false) {
return "you are following";
return "You are following";
} else if (isFollowing === false && isBlocking === true) {
return "you are blocking";
return "You are blocking";
} else if (isFollowing === false && isBlocking === false) {
return "you are not following or blocking";
return "You are not following or blocking";
} else {
return "you are following and blocking (!)";
return "You are following and blocking (!)";
}
}
};
@ -1105,6 +1107,7 @@ module.exports = cooler => {
models.post = post;
models.vote = {
/** @param {{messageKey: string, value: {}, recps: []}} input */
publish: async ({ messageKey, value, recps }) => {
const ssb = await cooler.connect();
const branch = await cooler.get(ssb.tangle.branch, messageKey);

View File

@ -4,20 +4,27 @@ const md = require("ssb-markdown");
const ssbMessages = require("ssb-msgs");
const ssbRef = require("ssb-ref");
const toUrl = (mentions = []) => {
const mentionNames = {};
/** @param {{ link: string}[]} mentions */
const toUrl = mentions => {
/** @type {{name: string, link: string}[]} */
const mentionNames = [];
ssbMessages.links(mentions, "feed").forEach(link => {
if (link.name && typeof link.name === "string") {
const name = link.name.charAt(0) === "@" ? link.name : `@${link.name}`;
mentionNames[name] = link.link;
/** @param {{ link: string, name: string}} arg */
const handleLink = ({ name, link }) => {
if (typeof name === "string") {
const atName = name.charAt(0) === "@" ? name : `@${name}`;
mentionNames.push({ name: atName, link });
}
});
};
return ref => {
ssbMessages.links(mentions, "feed").forEach(handleLink);
/** @param {string} ref */
const urlHandler = ref => {
// @mentions
if (ref in mentionNames) {
return `/author/${encodeURIComponent(mentionNames[ref])}`;
const found = mentionNames.find(({ name }) => name === ref);
if (found !== undefined) {
return `/author/${encodeURIComponent(found.link)}`;
}
if (ssbRef.isFeedId(ref)) {
@ -34,9 +41,15 @@ const toUrl = (mentions = []) => {
}
return "";
};
return urlHandler;
};
module.exports = (input, mentions) =>
/**
* @param {string} input
* @param {{name: string, link: string}[]} mentions
*/
module.exports = (input, mentions = []) =>
md.block(input, {
toUrl: toUrl(mentions)
});

View File

@ -7,6 +7,7 @@
const ssbClient = require("ssb-client");
const ssbConfig = require("ssb-config");
const flotilla = require("@fraction/flotilla");
const ssbTangle = require("ssb-tangle");
const debug = require("debug")("oasis");
const server = flotilla(ssbConfig);
@ -24,6 +25,15 @@ const rawConnect = () =>
if (err) {
reject(err);
} else {
if (api.tangle === undefined) {
// HACK: SSB-Tangle isn't available in Patchwork, but we want that
// compatibility. This code automatically injects SSB-Tangle into our
// stack so that we don't get weird errors when using Patchwork.
//
// See: https://github.com/fraction/oasis/issues/21
api.tangle = ssbTangle.init(api);
}
resolve(api);
}
});

View File

@ -46,9 +46,9 @@ exports.authorView = ({
const mention = `[@${name}](${feedId})`;
const markdownMention = highlightJs.highlight("markdown", mention).value;
const areFollowing = relationship === "you are following";
const areFollowing = relationship === "You are following";
const contactFormType = areFollowing ? "unfollow" : "follow";
const contactFormType = areFollowing ? "Unfollow" : "Follow";
// We're on our own profile!
const contactForm =
@ -82,7 +82,7 @@ exports.authorView = ({
? article({ innerHTML: description })
: null,
footer(
a({ href: `/likes/${encodeURIComponent(feedId)}` }, "view likes"),
a({ href: `/likes/${encodeURIComponent(feedId)}` }, "View likes"),
span(relationship),
contactForm
)
@ -150,7 +150,7 @@ exports.commentView = async ({ messages, myFeedId, parentMessage }) => {
{
type: "submit"
},
"comment"
"Comment"
)
)
);
@ -260,7 +260,7 @@ exports.metaView = ({ status, peers, theme, themeNames }) => {
form(
{ action: "/theme.css", method: "post" },
select({ name: "theme" }, ...themeElements),
button({ type: "submit" }, "set theme")
button({ type: "submit" }, "Set theme")
),
base16Elements,
h2("Status"),
@ -301,7 +301,7 @@ exports.publicView = ({ messages, prefix = null }) => {
". Messages cannot be edited or deleted."
),
textarea({ required: true, name: "text" }),
button({ type: "submit" }, "submit")
button({ type: "submit" }, "Submit")
)
),
messages.map(msg => post({ msg }))
@ -355,7 +355,7 @@ exports.replyView = async ({ messages, myFeedId }) => {
{
type: "submit"
},
"reply"
"Reply"
)
)
);
@ -376,7 +376,7 @@ exports.searchView = ({ messages, query }) =>
{
type: "submit"
},
"submit"
"Submit"
)
)
),

View File

@ -152,9 +152,9 @@ module.exports = ({ msg }) => {
`${likeCount}`
)
),
a({ href: url.comment }, "comment"),
isPrivate || isRoot || isFork ? null : a({ href: url.reply }, "reply"),
a({ href: url.json }, "json")
a({ href: url.comment }, "Comment"),
isPrivate || isRoot || isFork ? null : a({ href: url.reply }, "Reply"),
a({ href: url.json }, "JSON")
)
);

View File

@ -43,13 +43,13 @@ module.exports = (...elements) => {
body(
nav(
ul(
li(a({ href: "/" }, "popular")),
li(a({ href: "/public/latest" }, "latest")),
li(a({ href: "/inbox" }, "inbox")),
li(a({ href: "/mentions" }, "mentions")),
li(a({ href: "/profile" }, "profile")),
li(a({ href: "/search" }, "search")),
li(a({ href: "/meta" }, "meta"))
li(a({ href: "/" }, "Popular")),
li(a({ href: "/public/latest" }, "Latest")),
li(a({ href: "/inbox" }, "Inbox")),
li(a({ href: "/mentions" }, "Mentions")),
li(a({ href: "/profile" }, "Profile")),
li(a({ href: "/search" }, "Search")),
li(a({ href: "/meta" }, "Meta"))
)
),
main({ id: "content" }, elements)