Reset repo
This commit is contained in:
commit
3fb754d9b7
|
@ -0,0 +1,4 @@
|
|||
elm.js
|
||||
bundle.js
|
||||
node_modules
|
||||
elm-stuff
|
|
@ -0,0 +1,30 @@
|
|||
Copyright (c) 2018-present, natjms
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* Neither the name of natjms nor the names of other
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1 @@
|
|||
# dbio - Share your bio via the InterPlanetary File System
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"version": "1.0.0",
|
||||
"summary": "",
|
||||
"repository": "https://github.com/natjms/dbio.git",
|
||||
"license": "BSD3",
|
||||
"source-directories": [
|
||||
"."
|
||||
],
|
||||
"exposed-modules": [],
|
||||
"dependencies": {
|
||||
"elm-lang/core": "5.1.1 <= v < 6.0.0",
|
||||
"elm-lang/html": "2.0.0 <= v < 3.0.0",
|
||||
"elm-lang/navigation": "2.0.0 <= v < 3.0.0",
|
||||
"elm-community/html-extra": "2.2.0 <= v < 3.0.0"
|
||||
},
|
||||
"elm-version": "0.18.0 <= v < 0.19.0"
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
"use strict"
|
||||
|
||||
const IpfsApi = require("ipfs-api");
|
||||
const ipfs = IpfsApi();
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const home = document.getElementById("page_home");
|
||||
const view = document.getElementById("page_view");
|
||||
|
||||
const node = document.getElementById("elm");
|
||||
|
||||
if (home)
|
||||
home_page(node);
|
||||
|
||||
if (view)
|
||||
view_page(node);
|
||||
});
|
||||
|
||||
function home_page(node) {
|
||||
const app = Elm.Publish.embed(node);
|
||||
|
||||
app.ports.pub.subscribe(function(obj) {
|
||||
const string = JSON.stringify(obj);
|
||||
|
||||
const stored_hash = ipfs.add(Buffer.from(string))
|
||||
.catch(error => alert(error))
|
||||
.then(file => app.ports.new_hash.send(file[0].hash));
|
||||
});
|
||||
}
|
||||
|
||||
function view_page(node) {
|
||||
const app = Elm.Retrieve.embed(node);
|
||||
const hash = window.location.hash.slice(1);
|
||||
|
||||
ipfs.cat(hash, { buffer: true })
|
||||
.catch((error) => window.location.href = "../index.html")
|
||||
.then((bio) => {
|
||||
const as_string = new TextDecoder("utf-8").decode(bio)
|
||||
app.ports.receive_bio.send(as_string)
|
||||
});
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "dbio",
|
||||
"version": "1.0.0",
|
||||
"description": "Share your bio via IPFS",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "http-server www -a 127.0.0.1 -p 3000",
|
||||
"build": "browserify js/index.js > www/bundle.js && elm make src/Publish.elm --output=www/elm.js && elm make src/Retrieve.elm --output=www/u/elm.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "natjms",
|
||||
"license": "BSD-3-Clause",
|
||||
"devDependencies": {
|
||||
"browserify": "^13.1.1",
|
||||
"ipfs-api": "^11.1.0",
|
||||
"http-server": "^0.9.0",
|
||||
"elm": "^0.18.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
port module Publish exposing (main)
|
||||
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onInput, onClick)
|
||||
import Navigation exposing (load)
|
||||
|
||||
|
||||
main =
|
||||
Html.program
|
||||
{ view = view
|
||||
, update = update
|
||||
, init = init
|
||||
, subscriptions = subscriptions
|
||||
}
|
||||
|
||||
|
||||
-- MODEL
|
||||
|
||||
type alias Desc =
|
||||
{ name : String
|
||||
, location : String
|
||||
, image : String
|
||||
, work : String
|
||||
, education : String
|
||||
, bio : String
|
||||
}
|
||||
|
||||
type alias Model =
|
||||
{ desc : Desc
|
||||
}
|
||||
|
||||
port pub : Desc -> Cmd msg
|
||||
|
||||
init : (Model, Cmd Msg)
|
||||
init =
|
||||
( { desc =
|
||||
{ name = ""
|
||||
, location = ""
|
||||
, image = ""
|
||||
, work = ""
|
||||
, education = ""
|
||||
, bio = ""
|
||||
}
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
div []
|
||||
[ input [ type_ "text", placeholder "Name", onInput Name] []
|
||||
, input [ type_ "text", placeholder "Location", onInput Location] []
|
||||
, input [ type_ "text", placeholder "IPFS image hash", onInput Image] []
|
||||
, div [ class "two-inputs" ]
|
||||
[ input [ type_ "text", placeholder "Work", onInput Work] []
|
||||
, input [ type_ "text", placeholder "Education", onInput Education] []
|
||||
]
|
||||
, textarea [ placeholder "Talk about yourself", onInput Bio] []
|
||||
, input [ type_ "submit", value "Publish", onClick Submit] []
|
||||
]
|
||||
|
||||
|
||||
|
||||
-- UPDATE
|
||||
updateName desc name = { desc | name = name }
|
||||
updateImage desc img = { desc | image = img }
|
||||
updateWork desc work = { desc | work = work }
|
||||
updateEducation desc education = { desc | education = education }
|
||||
updateLocation desc location = { desc | location = location }
|
||||
updateBio desc bio = { desc | bio = bio }
|
||||
|
||||
type Msg
|
||||
= Name String
|
||||
| Image String
|
||||
| Work String
|
||||
| Education String
|
||||
| Location String
|
||||
| Bio String
|
||||
| Submit
|
||||
| Navigate String
|
||||
|
||||
|
||||
update : Msg -> Model -> (Model, Cmd msg)
|
||||
update msg model =
|
||||
case msg of
|
||||
Name new ->
|
||||
( { model |
|
||||
desc = updateName model.desc new
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
Image new ->
|
||||
( { model |
|
||||
desc = updateImage model.desc new
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
Work new ->
|
||||
( { model |
|
||||
desc = updateWork model.desc new
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
Education new ->
|
||||
( { model |
|
||||
desc = updateEducation model.desc new
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
Location new ->
|
||||
( { model |
|
||||
desc = updateLocation model.desc new
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
Bio new ->
|
||||
( { model |
|
||||
desc = updateBio model.desc new
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
Submit ->
|
||||
( model
|
||||
, pub model.desc
|
||||
)
|
||||
Navigate hash ->
|
||||
( model
|
||||
, load ("u/#" ++ hash)
|
||||
)
|
||||
|
||||
|
||||
-- SUBSCRIPTIONS
|
||||
|
||||
|
||||
port new_hash : (String -> msg) -> Sub msg
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions model =
|
||||
new_hash Navigate
|
|
@ -0,0 +1,118 @@
|
|||
port module Retrieve exposing (main)
|
||||
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onInput, onClick)
|
||||
import Json.Decode exposing (..)
|
||||
import Navigation exposing (load)
|
||||
import Result exposing (withDefault)
|
||||
import Html.Attributes.Extra exposing (innerHtml)
|
||||
|
||||
|
||||
main =
|
||||
Html.program
|
||||
{ view = view
|
||||
, update = update
|
||||
, init = init
|
||||
, subscriptions = subscriptions
|
||||
}
|
||||
|
||||
|
||||
-- MODEL
|
||||
|
||||
type alias Model =
|
||||
{ name : String
|
||||
, location : String
|
||||
, image : String
|
||||
, work : String
|
||||
, education : String
|
||||
, bio : String
|
||||
}
|
||||
|
||||
init : (Model, Cmd Msg)
|
||||
init =
|
||||
( { name = ""
|
||||
, location = ""
|
||||
, image = ""
|
||||
, work = ""
|
||||
, education = ""
|
||||
, bio = ""
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
ipfsGateway : String
|
||||
ipfsGateway = "https://ipfs.io/ipfs/"
|
||||
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
div [ class "row" ]
|
||||
[ div [ class "image col-md-8 col-sm-8" ]
|
||||
[ img [ src (ipfsGateway ++ model.image) ] []
|
||||
]
|
||||
, div [ class "content col-md-4 col-sm-4"]
|
||||
[ h1 [] [ text model.name ]
|
||||
, p [ class "subheader" ] [ text model.location ]
|
||||
, p [ innerHtml model.bio ] []
|
||||
, div [ class "container-fluid" ]
|
||||
[ div [ class "row" ]
|
||||
[ div [ class "col-md-6 col-sm-6" ]
|
||||
[ h3 [] [ text "Work" ]
|
||||
, p [] [ text model.work ]
|
||||
]
|
||||
, div [ class "col-md-6 col-sm-6" ]
|
||||
[ h3 [] [ text "Education" ]
|
||||
, p [] [ text model.education ]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
-- UPDATE
|
||||
|
||||
type Msg
|
||||
= Retrieved String
|
||||
| Error
|
||||
|
||||
update : Msg -> Model -> (Model, Cmd msg)
|
||||
update msg model =
|
||||
case msg of
|
||||
Retrieved json ->
|
||||
( { name =
|
||||
decodeString (field "name" string) json
|
||||
|> withDefault "Somebody"
|
||||
, location =
|
||||
decodeString (field "location" string) json
|
||||
|> withDefault "Somewhere"
|
||||
, image =
|
||||
decodeString (field "image" string) json
|
||||
|> withDefault "QmSVUVwKHMgBxy98N3vKkB6RQ4Umxd2mFd4uoMLpmqYKLW"
|
||||
, work =
|
||||
decodeString (field "work" string) json
|
||||
|> withDefault "A job"
|
||||
, education =
|
||||
decodeString (field "education" string) json
|
||||
|> withDefault "Some school"
|
||||
, bio =
|
||||
decodeString (field "bio" string) json
|
||||
|> withDefault "Nothing to show..."
|
||||
}
|
||||
, Cmd.none
|
||||
)
|
||||
Error ->
|
||||
(model, load "../index.html")
|
||||
|
||||
|
||||
-- SUBSCRIPTIONS
|
||||
|
||||
|
||||
port receive_bio : (String -> msg) -> Sub msg
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions model =
|
||||
receive_bio Retrieved
|
|
@ -0,0 +1,50 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>dbio</title>
|
||||
<link rel="stylesheet" href="https://ipfs.io/ipfs/QmPEJx9Bur2NNDPtBNT5zQ6bBnCkgYtKeNBAWRXx4j5hf2/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="page_home">
|
||||
<div class="jumbotron">
|
||||
<h1>
|
||||
dbio - decentralized profiles
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="container form">
|
||||
<div class="form-inner">
|
||||
<form action="#">
|
||||
<div id="elm"></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="about">
|
||||
<div class="container">
|
||||
<h2>What is dbio?</h2>
|
||||
<p>
|
||||
Dbio is a simple tool, similar to about.me, that you can use to share
|
||||
your bio. Unlike about.me, dbio users don't have to trust a central
|
||||
server: all the content you publish is added to IPFS - the permanet
|
||||
web. You seed your own bio from your own IPFS node.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
By the way, you can only publish to writeable nodes. Make sure the
|
||||
gateway you're using is writeable!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="container">
|
||||
<p>© 2018 natjms</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="elm.js"></script>
|
||||
<script src="bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,67 @@
|
|||
body {
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.jumbotron {
|
||||
background-color: #3498db;
|
||||
height: 200px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.jumbotron h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form {
|
||||
padding-top: 40px;
|
||||
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
.form-inner {
|
||||
width: 500px;
|
||||
max-width: 90%;
|
||||
margin: 0 auto
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-bottom: 1px solid black
|
||||
}
|
||||
|
||||
input[type=submit] {
|
||||
border-bottom: none;
|
||||
background-color: #3498db;
|
||||
color: #2c3e50;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
.two-inputs > input {
|
||||
width: 49%
|
||||
}
|
||||
|
||||
.two-inputs > input:last-child {
|
||||
margin-left: 5px
|
||||
}
|
||||
|
||||
.about {
|
||||
background-color: #ecf0f1;
|
||||
padding-top: 10vh;
|
||||
padding-bottom: 10vh;
|
||||
font-size: 1.5em
|
||||
}
|
||||
|
||||
.about h2 {
|
||||
font-size: 2em;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.footer {
|
||||
padding-top: 10px;
|
||||
font-size: 1.2em;
|
||||
text-align: center;
|
||||
background-color: #34495e;
|
||||
color: #ecf0f1
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title data-feild="name">dbio</title>
|
||||
<link rel="stylesheet" href="https://ipfs.io/ipfs/QmPEJx9Bur2NNDPtBNT5zQ6bBnCkgYtKeNBAWRXx4j5hf2/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="page_view">
|
||||
|
||||
<div class="container-fluid">
|
||||
<div id="elm"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="elm.js"></script>
|
||||
<script src="../bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,70 @@
|
|||
h1 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em
|
||||
}
|
||||
|
||||
h2, h3, h4, h5, h6 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h2, .subheader {
|
||||
font-weight: bold;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
h3 { font-size: 1em }
|
||||
h4 { font-size: 0.9em }
|
||||
h5 { font-size: 0.8em }
|
||||
h6 { font-size: 0.8em }
|
||||
|
||||
.subheader {
|
||||
font-size: 1.1em;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 50px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.image {
|
||||
height: 100vh;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.image > img {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
.location {
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.content {
|
||||
max-height: 100vh;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
.image { height: 50vh }
|
||||
.image > img { height: 50vh }
|
||||
|
||||
.content {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue