Moved most functionality to react. Update profile still needs to be moved. And the UI needs a bit of a makeover.
This commit is contained in:
parent
7701264a5c
commit
6c554ee56d
|
@ -3,3 +3,4 @@ node_modules/
|
|||
dist/
|
||||
config/production/password
|
||||
config/livenet/password
|
||||
chains.json
|
|
@ -1,587 +0,0 @@
|
|||
/*!
|
||||
* Bootstrap v3.3.6 (http://getbootstrap.com)
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
.btn-default,
|
||||
.btn-primary,
|
||||
.btn-success,
|
||||
.btn-info,
|
||||
.btn-warning,
|
||||
.btn-danger {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-primary:active,
|
||||
.btn-success:active,
|
||||
.btn-info:active,
|
||||
.btn-warning:active,
|
||||
.btn-danger:active,
|
||||
.btn-default.active,
|
||||
.btn-primary.active,
|
||||
.btn-success.active,
|
||||
.btn-info.active,
|
||||
.btn-warning.active,
|
||||
.btn-danger.active {
|
||||
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-primary.disabled,
|
||||
.btn-success.disabled,
|
||||
.btn-info.disabled,
|
||||
.btn-warning.disabled,
|
||||
.btn-danger.disabled,
|
||||
.btn-default[disabled],
|
||||
.btn-primary[disabled],
|
||||
.btn-success[disabled],
|
||||
.btn-info[disabled],
|
||||
.btn-warning[disabled],
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
fieldset[disabled] .btn-primary,
|
||||
fieldset[disabled] .btn-success,
|
||||
fieldset[disabled] .btn-info,
|
||||
fieldset[disabled] .btn-warning,
|
||||
fieldset[disabled] .btn-danger {
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.btn-default .badge,
|
||||
.btn-primary .badge,
|
||||
.btn-success .badge,
|
||||
.btn-info .badge,
|
||||
.btn-warning .badge,
|
||||
.btn-danger .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.btn:active,
|
||||
.btn.active {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-default {
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dbdbdb;
|
||||
border-color: #ccc;
|
||||
}
|
||||
.btn-default:hover,
|
||||
.btn-default:focus {
|
||||
background-color: #e0e0e0;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
border-color: #dbdbdb;
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-default[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
.btn-default.disabled:hover,
|
||||
.btn-default[disabled]:hover,
|
||||
fieldset[disabled] .btn-default:hover,
|
||||
.btn-default.disabled:focus,
|
||||
.btn-default[disabled]:focus,
|
||||
fieldset[disabled] .btn-default:focus,
|
||||
.btn-default.disabled.focus,
|
||||
.btn-default[disabled].focus,
|
||||
fieldset[disabled] .btn-default.focus,
|
||||
.btn-default.disabled:active,
|
||||
.btn-default[disabled]:active,
|
||||
fieldset[disabled] .btn-default:active,
|
||||
.btn-default.disabled.active,
|
||||
.btn-default[disabled].active,
|
||||
fieldset[disabled] .btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-primary {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary:hover,
|
||||
.btn-primary:focus {
|
||||
background-color: #265a88;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-primary:active,
|
||||
.btn-primary.active {
|
||||
background-color: #265a88;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary.disabled,
|
||||
.btn-primary[disabled],
|
||||
fieldset[disabled] .btn-primary,
|
||||
.btn-primary.disabled:hover,
|
||||
.btn-primary[disabled]:hover,
|
||||
fieldset[disabled] .btn-primary:hover,
|
||||
.btn-primary.disabled:focus,
|
||||
.btn-primary[disabled]:focus,
|
||||
fieldset[disabled] .btn-primary:focus,
|
||||
.btn-primary.disabled.focus,
|
||||
.btn-primary[disabled].focus,
|
||||
fieldset[disabled] .btn-primary.focus,
|
||||
.btn-primary.disabled:active,
|
||||
.btn-primary[disabled]:active,
|
||||
fieldset[disabled] .btn-primary:active,
|
||||
.btn-primary.disabled.active,
|
||||
.btn-primary[disabled].active,
|
||||
fieldset[disabled] .btn-primary.active {
|
||||
background-color: #265a88;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success:hover,
|
||||
.btn-success:focus {
|
||||
background-color: #419641;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-success:active,
|
||||
.btn-success.active {
|
||||
background-color: #419641;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success.disabled,
|
||||
.btn-success[disabled],
|
||||
fieldset[disabled] .btn-success,
|
||||
.btn-success.disabled:hover,
|
||||
.btn-success[disabled]:hover,
|
||||
fieldset[disabled] .btn-success:hover,
|
||||
.btn-success.disabled:focus,
|
||||
.btn-success[disabled]:focus,
|
||||
fieldset[disabled] .btn-success:focus,
|
||||
.btn-success.disabled.focus,
|
||||
.btn-success[disabled].focus,
|
||||
fieldset[disabled] .btn-success.focus,
|
||||
.btn-success.disabled:active,
|
||||
.btn-success[disabled]:active,
|
||||
fieldset[disabled] .btn-success:active,
|
||||
.btn-success.disabled.active,
|
||||
.btn-success[disabled].active,
|
||||
fieldset[disabled] .btn-success.active {
|
||||
background-color: #419641;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info:hover,
|
||||
.btn-info:focus {
|
||||
background-color: #2aabd2;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-info:active,
|
||||
.btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info.disabled,
|
||||
.btn-info[disabled],
|
||||
fieldset[disabled] .btn-info,
|
||||
.btn-info.disabled:hover,
|
||||
.btn-info[disabled]:hover,
|
||||
fieldset[disabled] .btn-info:hover,
|
||||
.btn-info.disabled:focus,
|
||||
.btn-info[disabled]:focus,
|
||||
fieldset[disabled] .btn-info:focus,
|
||||
.btn-info.disabled.focus,
|
||||
.btn-info[disabled].focus,
|
||||
fieldset[disabled] .btn-info.focus,
|
||||
.btn-info.disabled:active,
|
||||
.btn-info[disabled]:active,
|
||||
fieldset[disabled] .btn-info:active,
|
||||
.btn-info.disabled.active,
|
||||
.btn-info[disabled].active,
|
||||
fieldset[disabled] .btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning:hover,
|
||||
.btn-warning:focus {
|
||||
background-color: #eb9316;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-warning:active,
|
||||
.btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning.disabled,
|
||||
.btn-warning[disabled],
|
||||
fieldset[disabled] .btn-warning,
|
||||
.btn-warning.disabled:hover,
|
||||
.btn-warning[disabled]:hover,
|
||||
fieldset[disabled] .btn-warning:hover,
|
||||
.btn-warning.disabled:focus,
|
||||
.btn-warning[disabled]:focus,
|
||||
fieldset[disabled] .btn-warning:focus,
|
||||
.btn-warning.disabled.focus,
|
||||
.btn-warning[disabled].focus,
|
||||
fieldset[disabled] .btn-warning.focus,
|
||||
.btn-warning.disabled:active,
|
||||
.btn-warning[disabled]:active,
|
||||
fieldset[disabled] .btn-warning:active,
|
||||
.btn-warning.disabled.active,
|
||||
.btn-warning[disabled].active,
|
||||
fieldset[disabled] .btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger:hover,
|
||||
.btn-danger:focus {
|
||||
background-color: #c12e2a;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-danger:active,
|
||||
.btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger.disabled,
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-danger,
|
||||
.btn-danger.disabled:hover,
|
||||
.btn-danger[disabled]:hover,
|
||||
fieldset[disabled] .btn-danger:hover,
|
||||
.btn-danger.disabled:focus,
|
||||
.btn-danger[disabled]:focus,
|
||||
fieldset[disabled] .btn-danger:focus,
|
||||
.btn-danger.disabled.focus,
|
||||
.btn-danger[disabled].focus,
|
||||
fieldset[disabled] .btn-danger.focus,
|
||||
.btn-danger.disabled:active,
|
||||
.btn-danger[disabled]:active,
|
||||
fieldset[disabled] .btn-danger:active,
|
||||
.btn-danger.disabled.active,
|
||||
.btn-danger[disabled].active,
|
||||
fieldset[disabled] .btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
background-image: none;
|
||||
}
|
||||
.thumbnail,
|
||||
.img-thumbnail {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.dropdown-menu > li > a:hover,
|
||||
.dropdown-menu > li > a:focus {
|
||||
background-color: #e8e8e8;
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.dropdown-menu > .active > a,
|
||||
.dropdown-menu > .active > a:hover,
|
||||
.dropdown-menu > .active > a:focus {
|
||||
background-color: #2e6da4;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.navbar-default {
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.navbar-default .navbar-nav > .open > a,
|
||||
.navbar-default .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
|
||||
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.navbar-brand,
|
||||
.navbar-nav > li > a {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
|
||||
}
|
||||
.navbar-inverse {
|
||||
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
|
||||
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.navbar-inverse .navbar-nav > .open > a,
|
||||
.navbar-inverse .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
|
||||
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||
}
|
||||
.navbar-inverse .navbar-brand,
|
||||
.navbar-inverse .navbar-nav > li > a {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
|
||||
}
|
||||
.navbar-static-top,
|
||||
.navbar-fixed-top,
|
||||
.navbar-fixed-bottom {
|
||||
border-radius: 0;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||
color: #fff;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
}
|
||||
.alert {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.alert-success {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b2dba1;
|
||||
}
|
||||
.alert-info {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #9acfea;
|
||||
}
|
||||
.alert-warning {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #f5e79e;
|
||||
}
|
||||
.alert-danger {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dca7a7;
|
||||
}
|
||||
.progress {
|
||||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-striped {
|
||||
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
}
|
||||
.list-group {
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.list-group-item.active,
|
||||
.list-group-item.active:hover,
|
||||
.list-group-item.active:focus {
|
||||
text-shadow: 0 -1px 0 #286090;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #2b669a;
|
||||
}
|
||||
.list-group-item.active .badge,
|
||||
.list-group-item.active:hover .badge,
|
||||
.list-group-item.active:focus .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.panel {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.panel-default > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-primary > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-success > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-info > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-warning > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-danger > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.well {
|
||||
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dcdcdc;
|
||||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-theme.css.map */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,49 @@
|
|||
|
||||
.logs {
|
||||
background-color: black;
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
border-left: 1px solid #ddd;
|
||||
border-right: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 10px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.status-offline {
|
||||
vertical-align: middle;
|
||||
margin-left: 5px;
|
||||
margin-top: 4px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: red;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.status-online {
|
||||
vertical-align: middle;
|
||||
margin-left: 5px;
|
||||
margin-top: 4px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: mediumseagreen;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
input.form-control {
|
||||
margin-right: 5px;
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
|
||||
#profile img {
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
#edit-profile, #edit-profile-photo {
|
||||
padding-top: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#edit-profile input, #edit-profile-photo input {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.createProfileView {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.editLink {
|
||||
margin-top: 5px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#edit-profile-info {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#tweets {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.editLink {
|
||||
color: blue;
|
||||
cursor: hand;
|
||||
}
|
|
@ -1,69 +1,21 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Demo</title>
|
||||
<link rel="stylesheet" href="css/app.css">
|
||||
<script src="js/app.js"></script>
|
||||
</head>
|
||||
<body class="container">
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<div class="navbar navbar-default navbar-fixed-top">
|
||||
<div class="viewUser row">
|
||||
<div class="left col-md-4">
|
||||
<input name="username" placeholder="profile username"/><button class="viewUsername btn btn-primary">view profile</button>
|
||||
</div>
|
||||
<div class="right col-md-8" align="right">
|
||||
<span class="createLink btn btn-primary">create account</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
<title>Decentralised Twitter dApp for DappCon 2018!</title>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
<link href="css/app.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<div class="main">
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<script type="text/javascript" src="js/app.js"></script>
|
||||
</body>
|
||||
|
||||
<div class="row createProfileView">
|
||||
<div id="create-profile">
|
||||
<strong>username: </strong><input type="text" class="form-control name" name="username">
|
||||
<strong>description: </strong><input type="text" class="form-control description" name="description">
|
||||
<button class="createProfile set btn btn-primary">create</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row profileView">
|
||||
|
||||
<div class="left col-md-4">
|
||||
<div id="profile"><img alt="Username" />
|
||||
<div class="profile-name">username</div>
|
||||
<div class="profile-description">..Description..</div>
|
||||
</div>
|
||||
|
||||
<span class="editLink">edit</span>
|
||||
|
||||
<div id="edit-profile-info">
|
||||
<div id="edit-profile">
|
||||
<strong>Edit Profile Description</strong>
|
||||
<input type="text" class="form-control description" name="description">
|
||||
<button class="editProfile set btn btn-primary">update description</button>
|
||||
</div>
|
||||
|
||||
<div id="edit-profile-photo">
|
||||
<strong>Upload Photo</strong>
|
||||
<input type="file" class="form-control">
|
||||
<button class="uploadFile set btn btn-primary">upload</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="right col-md-8">
|
||||
<div id="doTweet">
|
||||
<input type="text" class="form-control name" name="text" placeholder="type text to be tweeted">
|
||||
<button class="set btn btn-primary">tweet</button>
|
||||
</div>
|
||||
|
||||
<div id="tweets">
|
||||
<div class="tweet"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
|
@ -1,42 +0,0 @@
|
|||
import $ from 'jquery';
|
||||
import imgAvatar from '../img/avatar-default.png';
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
$('#profile img').attr('src', imgAvatar);
|
||||
|
||||
$(".editLink").click(function() {
|
||||
$("#edit-profile-info").slideToggle();
|
||||
});
|
||||
|
||||
$(".createLink").click(function() {
|
||||
$(".createProfileView").show();
|
||||
$(".profileView").hide();
|
||||
});
|
||||
|
||||
$(".viewUsername").click(function() {
|
||||
$(".createProfileView").hide();
|
||||
$(".profileView").show();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
window.updateProfile = function(opts) {
|
||||
let username = opts.username;
|
||||
let description = opts.description;
|
||||
let photo = opts.picture;
|
||||
if (photo == null || photo == EmbarkJS.Storage.getUrl('')) {
|
||||
//photo = "http://i.imgur.com/xAmv5AO.jpg";
|
||||
photo = imgAvatar;
|
||||
}
|
||||
|
||||
$(".profileView .profile-name").html(username);
|
||||
$(".profileView .profile-description").html(description);
|
||||
$(".profileView img").attr('src', photo).attr('alt', username);
|
||||
};
|
||||
|
||||
window.addTweet = function(tweet) {
|
||||
$("#tweets").prepend('<blockquote><div class="tweet well">' + tweet.text + '</div></blockquote>');
|
||||
};
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,18 @@
|
|||
import Header from './Header'
|
||||
import Main from './Main'
|
||||
|
||||
import {DTwitter} from 'Embark/contracts';
|
||||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
import React from 'react';
|
||||
|
||||
window.EmbarkJS = EmbarkJS;
|
||||
window.DTwitter = DTwitter;
|
||||
|
||||
const App = () => (
|
||||
<div>
|
||||
<Header />
|
||||
<Main />
|
||||
</div>
|
||||
)
|
||||
|
||||
export default App
|
|
@ -0,0 +1,136 @@
|
|||
import { Button, FormGroup, ControlLabel, FormControl, HelpBlock } from 'react-bootstrap';
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import React from 'react';
|
||||
|
||||
class CreateUser extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
// event bindings
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
|
||||
// initial state
|
||||
this.state = {
|
||||
isLoading: false,
|
||||
username: '',
|
||||
description: '',
|
||||
userExists: false,
|
||||
usernameHasChanged: false
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Events
|
||||
*/
|
||||
handleClick() {
|
||||
this.setState({ isLoading: true });
|
||||
EmbarkJS.onReady(() => {
|
||||
console.log('creating account with username = ' + this.state.username + ', and description = ' + this.state.description);
|
||||
DTwitter.methods.createAccount(this.state.username, this.state.description).send({ gas: 800000 }).then(() => {
|
||||
console.log('account created event fired: ' + JSON.stringify(event));
|
||||
// Completed of async action, set loading state back
|
||||
this.setState({ isLoading: false });
|
||||
this.props.history.push('/@' + this.state.username);
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
this.setState({ isLoading: false, error: err.message });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
handleChange(e) {
|
||||
let state = {usernameHasChanged: true};
|
||||
const input = e.target.name;
|
||||
const value = e.target.value;
|
||||
|
||||
state[input] = value;
|
||||
console.log('this.state = ' + JSON.stringify(this.state));
|
||||
if (input === 'username' && value.length >= 5) {
|
||||
// not loading, check username doesn't exist
|
||||
if (!this.state.isLoading) {
|
||||
console.log('checking if username exists: ' + value);
|
||||
DTwitter.methods.userExists(value).call().then((exists) => {
|
||||
console.log(`response username '${value}' exists: ${exists}`);
|
||||
state.isLoading = false;
|
||||
state.userExists = exists;
|
||||
this.setState(state);
|
||||
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
state.isLoading = false;
|
||||
state.userExists = exists;
|
||||
state.error = err.message;
|
||||
this.setState(state);
|
||||
});
|
||||
console.log('sent async username check, setting isLoading is true');
|
||||
// set loading state while checking the contract
|
||||
return this.setState({ isLoading: true });
|
||||
}
|
||||
|
||||
// we are loading already, do nothing while we wait
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper methods
|
||||
*/
|
||||
getValidationState() {
|
||||
if (this.state.isLoading) return null;
|
||||
|
||||
const length = this.state.username.length;
|
||||
if(length === 0 && !this.state.usernameHasChanged) return null;
|
||||
if (length <= 5) return 'error';
|
||||
|
||||
return this.state.userExists ? 'error' : 'success';
|
||||
}
|
||||
|
||||
/**
|
||||
* React methods
|
||||
*/
|
||||
render() {
|
||||
const { isLoading } = this.state;
|
||||
let validationState = this.getValidationState();
|
||||
let isValid = validationState !== 'error';
|
||||
|
||||
return (
|
||||
<form>
|
||||
<FormGroup
|
||||
controlId="formBasicText"
|
||||
validationState={validationState}
|
||||
>
|
||||
<ControlLabel>Enter desired username</ControlLabel>
|
||||
<FormControl
|
||||
type="text"
|
||||
value={this.state.username}
|
||||
disabled={isLoading}
|
||||
placeholder="@username"
|
||||
onChange={this.handleChange}
|
||||
name="username"
|
||||
/>
|
||||
<FormControl
|
||||
type="text"
|
||||
value={this.state.description}
|
||||
placeholder="description"
|
||||
onChange={this.handleChange}
|
||||
name="description"
|
||||
/>
|
||||
<Button
|
||||
bsStyle="primary"
|
||||
disabled={isLoading || !isValid}
|
||||
onClick={(isLoading || !isValid) ? null : this.handleClick}
|
||||
>
|
||||
{isLoading ? 'Loading...' : 'Create user'}
|
||||
</Button>
|
||||
<FormControl.Feedback />
|
||||
<HelpBlock>{this.state.error || 'Usernames must be 5 or more characters.'}</HelpBlock>
|
||||
</FormGroup>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(CreateUser);
|
|
@ -0,0 +1,91 @@
|
|||
import { Link } from 'react-router-dom'
|
||||
import { Button, FormGroup, ControlLabel, FormControl, HelpBlock } from 'react-bootstrap';
|
||||
import React from 'react';
|
||||
|
||||
// The Header creates links that can be used to navigate
|
||||
// between routes.
|
||||
class DoTweet extends React.Component{
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
// properties pass-through
|
||||
const { username, visible } = props;
|
||||
console.log('Do Tweet: username = '+ username + ', visible = ' + visible);
|
||||
|
||||
// event bindings
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
|
||||
// initial state
|
||||
this.state = {
|
||||
visible: visible,
|
||||
username: username,
|
||||
tweet: '',
|
||||
tweetHasChanged: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Events
|
||||
*/
|
||||
handleClick(e) {
|
||||
if(this.getValidationState() === 'error'){
|
||||
return e.preventDefault();
|
||||
}
|
||||
|
||||
// send tweet to the contract
|
||||
DTwitter.methods.tweet(this.props.username, this.state.tweet).send({gas: 800000});
|
||||
}
|
||||
|
||||
handleChange(e) {
|
||||
let state = {tweetHasChanged: true};
|
||||
state[e.target.name] = e.target.value;
|
||||
this.setState(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper methods
|
||||
*/
|
||||
getValidationState() {
|
||||
return ((this.state.tweet === '' && !this.state.tweetHasChanged) || (this.state.tweet.length > 0 && this.state.tweet.length <= 140)) ? null : 'error';
|
||||
}
|
||||
|
||||
render(){
|
||||
// hide when not visible
|
||||
if(!this.props.visible) return null;
|
||||
|
||||
let validationState = this.getValidationState();
|
||||
let isValid = validationState !== 'error';
|
||||
|
||||
|
||||
return (
|
||||
<form>
|
||||
<FormGroup
|
||||
controlId="formBasicText"
|
||||
validationState={validationState}
|
||||
>
|
||||
<FormControl
|
||||
type="text"
|
||||
value={this.state.tweet}
|
||||
placeholder="140 characters or less..."
|
||||
onChange={this.handleChange}
|
||||
name="tweet"
|
||||
componentClass="textarea"
|
||||
maxLength="140"
|
||||
/>
|
||||
<Button
|
||||
bsStyle="primary"
|
||||
disabled={!isValid}
|
||||
onClick={!isValid ? null : this.handleClick}
|
||||
>Post tweet</Button>
|
||||
<FormControl.Feedback />
|
||||
</FormGroup>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default DoTweet
|
|
@ -0,0 +1,92 @@
|
|||
import { Link, withRouter } from 'react-router-dom'
|
||||
import { Button, FormGroup, ControlLabel, FormControl, HelpBlock } from 'react-bootstrap';
|
||||
import React from 'react';
|
||||
|
||||
// The Header creates links that can be used to navigate
|
||||
// between routes.
|
||||
class Header extends React.Component{
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
// event bindings
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
|
||||
// initial state
|
||||
this.state = {
|
||||
username: '',
|
||||
usernameHasChanged: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
//this.setState({username: this.props.match.username});
|
||||
}
|
||||
|
||||
/**
|
||||
* Events
|
||||
*/
|
||||
handleClick(e) {
|
||||
console.log('handling click, validations state = ' + this.getValidationState());
|
||||
if(this.getValidationState() === 'error'){
|
||||
return e.preventDefault();
|
||||
}
|
||||
this.props.history.push('/@' + this.state.username);
|
||||
}
|
||||
|
||||
handleChange(e) {
|
||||
let state = {usernameHasChanged: true};
|
||||
state[e.target.name] = e.target.value;
|
||||
this.setState(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper methods
|
||||
*/
|
||||
getValidationState() {
|
||||
return (this.state.username === '' && !this.state.usernameHasChanged) || this.state.username.length > 0 ? null : 'error';
|
||||
}
|
||||
|
||||
render(){
|
||||
|
||||
let validationState = this.getValidationState();
|
||||
let isValid = validationState !== 'error';
|
||||
|
||||
return (
|
||||
<form>
|
||||
<Link to='/create'>Create user</Link>
|
||||
<FormGroup
|
||||
controlId="formBasicText"
|
||||
validationState={validationState}
|
||||
>
|
||||
<FormControl
|
||||
type="text"
|
||||
value={this.state.username}
|
||||
placeholder="@username"
|
||||
onChange={this.handleChange}
|
||||
name="username"
|
||||
/>
|
||||
<Button
|
||||
bsStyle="primary"
|
||||
disabled={!isValid}
|
||||
onClick={!isValid ? null : this.handleClick}
|
||||
|
||||
>Get tweets</Button>
|
||||
<FormControl.Feedback />
|
||||
</FormGroup>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
// const Header = () => (
|
||||
// <header>
|
||||
// <nav>
|
||||
// <ul>
|
||||
// <li><Link to='/'>Home</Link></li>
|
||||
// <li><Link to='/create'>Create user</Link></li>
|
||||
// </ul>
|
||||
// <input type="text" placeholder="@username"/><button id="btnGetUserTweets">Get Tweets</button>
|
||||
// </nav>
|
||||
// </header>
|
||||
// )
|
||||
}
|
||||
export default withRouter(Header)
|
|
@ -0,0 +1,9 @@
|
|||
import React from 'react';
|
||||
|
||||
const Home = () => (
|
||||
<div>
|
||||
<h1>Decentralised Twitter dApp for DappCon 2018!</h1>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default Home
|
|
@ -0,0 +1,24 @@
|
|||
import { Switch, Route } from 'react-router-dom'
|
||||
import Home from './Home'
|
||||
import UserTweets from './UserTweets'
|
||||
import CreateUser from './CreateUser'
|
||||
import UpdateUser from './UpdateUser'
|
||||
import React from 'react';
|
||||
|
||||
// The Main component renders one of the three provided
|
||||
// Routes (provided that one matches). Both the /roster
|
||||
// and /schedule routes will match any pathname that starts
|
||||
// with /roster or /schedule. The / route will only match
|
||||
// when the pathname is exactly the string "/"
|
||||
const Main = () => (
|
||||
<main>
|
||||
<Switch>
|
||||
<Route exact path='/' component={Home}/>
|
||||
<Route path='/@:username' component={UserTweets}/>
|
||||
<Route path='/create' component={CreateUser}/>
|
||||
<Route path='/update/@:username' component={UpdateUser}/>
|
||||
</Switch>
|
||||
</main>
|
||||
)
|
||||
|
||||
export default Main
|
|
@ -0,0 +1,7 @@
|
|||
import React from 'react';
|
||||
|
||||
class UpdateUser extends React.Component{
|
||||
|
||||
}
|
||||
|
||||
export default UpdateUser;
|
|
@ -0,0 +1,101 @@
|
|||
import { Link } from 'react-router-dom';
|
||||
import {Grid, Row, Col, Thumbnail, ListGroup, ListGroupItem } from 'react-bootstrap';
|
||||
import React from 'react';
|
||||
import imgAvatar from '../../img/avatar-default.png';
|
||||
import DoTweet from './DoTweet';
|
||||
|
||||
// The Player looks up the player using the number parsed from
|
||||
// the URL's pathname. If no player is found with the given
|
||||
// number, then a "player not found" message is displayed.
|
||||
class UserTweets extends React.Component {
|
||||
|
||||
constructor(props, context){
|
||||
super(props, context);
|
||||
this.state = {
|
||||
user: {},
|
||||
account: '',
|
||||
tweets: []
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
const self = this;
|
||||
EmbarkJS.onReady(() => {
|
||||
// get user details and update state
|
||||
DTwitter.methods.users(web3.utils.keccak256(this.props.match.params.username)).call().then((user) => {
|
||||
user.picture = user.picture.length > 0 ? EmbarkJS.Storage.getUrl(user.picture) : imgAvatar;
|
||||
console.log('user: ' + JSON.stringify(user));
|
||||
this.setState({user: user});
|
||||
}).catch(console.error);
|
||||
|
||||
// so we can check our current node accounts to see if we are the owner of this account
|
||||
web3.eth.getAccounts().then((accounts) => {
|
||||
console.log('got accounts: ' + accounts);
|
||||
if(accounts.length){
|
||||
this.setState({account: accounts[0]});
|
||||
}
|
||||
}).catch(console.error);
|
||||
|
||||
// subscribe to tweet events
|
||||
DTwitter.events.NewTweet({_from: web3.utils.keccak256(this.props.match.params.username), fromBlock: 0})
|
||||
.on('data', function (event){
|
||||
console.log('new tweet event fired: ' + JSON.stringify(event));
|
||||
let index = parseInt(event.returnValues.index);
|
||||
console.log('calling getTweet with index ' + index);
|
||||
DTwitter.methods.getTweet(self.props.match.params.username, index).call().then(function(tweet) {
|
||||
console.log('get tweet at index ' + index + ': ' + JSON.stringify(tweet));
|
||||
let tweets = self.state.tweets;
|
||||
tweets.push(tweet);
|
||||
self.setState({tweets: tweets});
|
||||
|
||||
}).catch(function(error){
|
||||
console.error('error getting tweet at index ' + index, error);
|
||||
});
|
||||
})
|
||||
.on('changed', function (event){
|
||||
console.warn('event removed: ' + JSON.stringify(event));
|
||||
})
|
||||
.on('error', function(error){
|
||||
console.error('error occurred with tweet event: ', error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render(){
|
||||
const {user} = this.state;
|
||||
const isEditable = this.state.account != '' && this.state.account === user.owner;
|
||||
|
||||
if (user === {}) {
|
||||
// Render loading state ...
|
||||
return (<div>Loading...</div>);
|
||||
} else if (user.username === ''){
|
||||
return (<div>User doesn't exist!</div>);
|
||||
}else {
|
||||
// Render real UI ...
|
||||
const {username, description, picture} = this.state.user;
|
||||
const tweetList = this.state.tweets.map(function(tweet, index){
|
||||
return <ListGroupItem key={index} header={username}>{tweet}</ListGroupItem>
|
||||
});
|
||||
return (
|
||||
<Grid>
|
||||
<Row>
|
||||
<Col xs={12} md={4}>
|
||||
<Thumbnail src={picture} alt={username} href={isEditable ? '/update/@' + username : ''}>
|
||||
<h3>{username}</h3>
|
||||
<p>{description}</p>
|
||||
</Thumbnail>
|
||||
<DoTweet username={username} visible={isEditable}></DoTweet>
|
||||
</Col>
|
||||
<Col xs={12} md={8}>
|
||||
<ListGroup>
|
||||
{tweetList}
|
||||
</ListGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
export default UserTweets
|
|
@ -0,0 +1,171 @@
|
|||
import { Alert, Form, FormGroup, FormControl, HelpBlock, Button } from 'react-bootstrap';
|
||||
import React from 'react';
|
||||
|
||||
class Storage extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
textToSave: 'hello world!',
|
||||
generatedHash: '',
|
||||
loadText: '',
|
||||
storedText: '',
|
||||
fileToUpload: null,
|
||||
fileHash: '',
|
||||
imageToDownload: '',
|
||||
url: '',
|
||||
logs: [],
|
||||
storageError: ''
|
||||
};
|
||||
}
|
||||
|
||||
handleChange(e, name){
|
||||
this.state[name] = e.target.value;
|
||||
this.setState(this.state);
|
||||
}
|
||||
|
||||
handleFileUpload(e){
|
||||
this.setState({ fileToUpload: [e.target] });
|
||||
}
|
||||
|
||||
addToLog(txt){
|
||||
this.state.logs.push(txt);
|
||||
this.setState({logs: this.state.logs});
|
||||
}
|
||||
|
||||
setText(e){
|
||||
e.preventDefault();
|
||||
|
||||
EmbarkJS.Storage.saveText(this.state.textToSave)
|
||||
.then((hash) => {
|
||||
this.setState({
|
||||
generatedHash: hash,
|
||||
loadText: hash,
|
||||
storageError: ''
|
||||
});
|
||||
this.addToLog("EmbarkJS.Storage.saveText('" + this.state.textToSave + "').then(function(hash) { })");
|
||||
})
|
||||
.catch((err) => {
|
||||
if(err){
|
||||
this.setState({storageError: err.message});
|
||||
console.log("Storage saveText Error => " + err.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadHash(e){
|
||||
e.preventDefault();
|
||||
|
||||
EmbarkJS.Storage.get(this.state.loadText)
|
||||
.then((content) => {
|
||||
this.setState({storedText: content, storageError: ''});
|
||||
this.addToLog("EmbarkJS.Storage.get('" + this.state.loadText + "').then(function(content) { })");
|
||||
})
|
||||
.catch((err) => {
|
||||
if(err){
|
||||
this.setState({storageError: err.message})
|
||||
console.log("Storage get Error => " + err.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
uploadFile(e){
|
||||
e.preventDefault();
|
||||
|
||||
EmbarkJS.Storage.uploadFile(this.state.fileToUpload)
|
||||
.then((hash) => {
|
||||
this.setState({
|
||||
fileHash: hash,
|
||||
imageToDownload: hash,
|
||||
storageError: ''
|
||||
});
|
||||
this.addToLog("EmbarkJS.Storage.uploadFile(this.state.fileToUpload).then(function(hash) { })");
|
||||
})
|
||||
.catch((err) => {
|
||||
if(err){
|
||||
this.setState({storageError: err.message});
|
||||
console.log("Storage uploadFile Error => " + err.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadFile(e){
|
||||
let _url = EmbarkJS.Storage.getUrl(this.state.imageToDownload);
|
||||
this.setState({url: _url})
|
||||
this.addToLog("EmbarkJS.Storage.getUrl('" + this.state.imageToDownload + "')");
|
||||
}
|
||||
|
||||
render(){
|
||||
return <React.Fragment>
|
||||
{
|
||||
!this.props.enabled ?
|
||||
<React.Fragment>
|
||||
<Alert bsStyle="warning">The node you are using does not support IPFS. Please ensure <a href="https://github.com/ipfs/js-ipfs-api#cors" target="_blank">CORS</a> is setup for the IPFS node.</Alert>
|
||||
</React.Fragment> : ''
|
||||
}
|
||||
{
|
||||
this.state.storageError !== '' ?
|
||||
<Alert bsStyle="danger">{this.state.storageError}</Alert>
|
||||
: ''
|
||||
}
|
||||
<h3>Save text to storage</h3>
|
||||
<Form inline>
|
||||
<FormGroup>
|
||||
<FormControl
|
||||
type="text"
|
||||
defaultValue={this.state.textToSave}
|
||||
onChange={e => this.handleChange(e, 'textToSave')} />
|
||||
<Button bsStyle="primary" onClick={(e) => this.setText(e)}>Save Text</Button>
|
||||
<HelpBlock>generated Hash: <span className="textHash">{this.state.generatedHash}</span></HelpBlock>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
|
||||
<h3>Load text from storage given an hash</h3>
|
||||
<Form inline>
|
||||
<FormGroup>
|
||||
<FormControl
|
||||
type="text"
|
||||
value={this.state.loadText}
|
||||
onChange={e => this.handleChange(e, 'loadText')} />
|
||||
<Button bsStyle="primary" onClick={(e) => this.loadHash(e)}>Load</Button>
|
||||
<HelpBlock>result: <span className="textHash">{this.state.storedText}</span></HelpBlock>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
|
||||
<h3>Upload file to storage</h3>
|
||||
<Form inline>
|
||||
<FormGroup>
|
||||
<FormControl
|
||||
type="file"
|
||||
onChange={(e) => this.handleFileUpload(e)} />
|
||||
<Button bsStyle="primary" onClick={(e) => this.uploadFile(e)}>Upload</Button>
|
||||
<HelpBlock>generated hash: <span className="fileHash">{this.state.fileHash}</span></HelpBlock>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
|
||||
<h3>Get file or image from storage</h3>
|
||||
<Form inline>
|
||||
<FormGroup>
|
||||
<FormControl
|
||||
type="text"
|
||||
value={this.state.imageToDownload}
|
||||
onChange={e => this.handleChange(e, 'imageToDownload')} />
|
||||
<Button bsStyle="primary" onClick={(e) => this.loadFile(e)}>Download</Button>
|
||||
<HelpBlock>file available at: <span><a href={this.state.url} target="_blank">{this.state.url}</a></span></HelpBlock>
|
||||
<HelpBlock><img src={this.state.url} /></HelpBlock>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
|
||||
<p>Javascript calls being made: </p>
|
||||
<div className="logs">
|
||||
<p>EmbarkJS.Storage.setProvider('ipfs',{'{'}server: 'localhost', port: '5001'{'}'})</p>
|
||||
{
|
||||
this.state.logs.map((item, i) => <p key={i}>{item}</p>)
|
||||
}
|
||||
</div>
|
||||
</React.Fragment>;
|
||||
}
|
||||
}
|
||||
|
||||
export default Storage;
|
|
@ -0,0 +1,10 @@
|
|||
import { render } from 'react-dom'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import App from './components/App';
|
||||
import React from 'react';
|
||||
|
||||
render((
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
), document.getElementById('root'));
|
|
@ -1,78 +0,0 @@
|
|||
import $ from 'jquery';
|
||||
import {DTwitter} from 'Embark/contracts';
|
||||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
|
||||
window.EmbarkJS = EmbarkJS;
|
||||
window.DTwitter = DTwitter;
|
||||
|
||||
let tweetEvent;
|
||||
$(document).ready(function() {
|
||||
|
||||
// Create Account
|
||||
$(".createProfile").click(function() {
|
||||
let username = $(".createProfileView input[name=username]").val();
|
||||
let description = $(".createProfileView input[name=description]").val();
|
||||
EmbarkJS.onReady(function(){
|
||||
DTwitter.methods.createAccount(username, description).send({gas: 800000});
|
||||
});
|
||||
});
|
||||
|
||||
// View Account
|
||||
$(".viewUsername").click(function() {
|
||||
let username = $(".viewUser input[name=username]").val();
|
||||
console.log('username: ' + username + ', hash: ' + web3.utils.keccak256(username));
|
||||
DTwitter.methods.users(web3.utils.keccak256(username)).call().then(function(user) {
|
||||
console.log('user: ' + JSON.stringify(user));
|
||||
updateProfile({
|
||||
username: user.username,
|
||||
description: user.description,
|
||||
picture: EmbarkJS.Storage.getUrl(user.picture)
|
||||
});
|
||||
});
|
||||
|
||||
if(!tweetEvent) return;
|
||||
|
||||
if (tweetEvent) {
|
||||
tweetEvent.stop();
|
||||
}
|
||||
|
||||
$("#tweets").empty();
|
||||
|
||||
// Listen to tweets
|
||||
tweetEvent = DTwitter.events.NewTweet({_from: web3.utils.keccak256(username)}, {fromBlock: 0});
|
||||
tweetEvent.then(function(event) {
|
||||
let index = event.args.index.toNumber();
|
||||
DTwitter.methods.getTweet(username, index).call().then(function(tweet) {
|
||||
addTweet({text: tweet});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Edit Account Description
|
||||
$("#edit-profile-info button").click(function() {
|
||||
let username = $(".viewUser input[name=username]").val();
|
||||
let description = $("#edit-profile-info .description").val();
|
||||
|
||||
DTwitter.methods.editAccount(username, description).send({gas: 800000});
|
||||
});
|
||||
|
||||
// Upload Photo
|
||||
$("#edit-profile-photo button").click(function() {
|
||||
let username = $(".viewUser input[name=username]").val();
|
||||
let uploadInput = $("input[type=file]");
|
||||
|
||||
EmbarkJS.Storage.uploadFile(uploadInput).then(function(hash) {
|
||||
DTwitter.methods.updateProfilePicture(username, hash).send({gas: 800000});
|
||||
});
|
||||
});
|
||||
|
||||
// Make a Tweet
|
||||
$("#doTweet button").click(function() {
|
||||
let username = $(".viewUser input[name=username]").val();
|
||||
let text = $("input[name=text]").val();
|
||||
|
||||
DTwitter.methods.tweet(username, text).send({gas: 800000});
|
||||
});
|
||||
|
||||
});
|
152
chains.json
152
chains.json
|
@ -35,7 +35,7 @@
|
|||
},
|
||||
"0x1797453304e4b69b44fb7d649a72ca80394a8b4e1d14c2cc530f5dc3ae1f0ea3": {
|
||||
"name": "ENSRegistry",
|
||||
"address": "0x4F11C0308398661b149727c225726b6A2f1Bd533"
|
||||
"address": "0x54cD1E7d22Be240C0F8728C2Daa51336447e532D"
|
||||
},
|
||||
"0xf7082984e1d389aef8e723917135a24b36de42604f88aaaa240e2fb530992c5d": {
|
||||
"name": "FIFSRegistrar",
|
||||
|
@ -115,11 +115,19 @@
|
|||
},
|
||||
"0xe5409c181a9197409bb86c1dac705b0cea3c4e30f361b42dbdaea7e7f1729a93": {
|
||||
"name": "DTwitter",
|
||||
"address": "0x1aAB77723bD0a27DD85A76Ae4c6f471dC8643e15"
|
||||
"address": "0xBc14A4C0A71D290ec86A6F2A4B0B26a64a9512B1"
|
||||
},
|
||||
"0x6d1e2e0bd96a493aaab99909e0fd4ed874e93edd9a58020916846e08876c3b01": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0xc97EB051Ea7544d2DEA2846b791212Ae938173c2"
|
||||
},
|
||||
"0x471afc554d47abbf4a63f004f2bb69bc54ab69908c3c21285bf2f32af72c0189": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x89114C48c7A31a936cA79Ed170E3AA7075204D21"
|
||||
},
|
||||
"0x19128eed1c8800a3f992243b8dad181ab39f3e207713d027d66229f40f952a48": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0xb9C97eD16F3f9CF645d14F37D14491BFb9FaB16F"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -146,5 +154,145 @@
|
|||
"address": "0x1124f45c80A2Fe638B1a9042125299bCB588A3D7"
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d": {
|
||||
"contracts": {
|
||||
"0x1797453304e4b69b44fb7d649a72ca80394a8b4e1d14c2cc530f5dc3ae1f0ea3": {
|
||||
"name": "ENSRegistry",
|
||||
"address": "0xa684Bd6FdfA41332069Dc5dE3A2c6dA2099A4012"
|
||||
},
|
||||
"0xe5409c181a9197409bb86c1dac705b0cea3c4e30f361b42dbdaea7e7f1729a93": {
|
||||
"name": "DTwitter",
|
||||
"address": "0x64b646dFA40e23fC5E681f9851861acBDa377D6d"
|
||||
},
|
||||
"0x6d1e2e0bd96a493aaab99909e0fd4ed874e93edd9a58020916846e08876c3b01": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x20d298a978bE2AE9A2533A1E53c49F1A7Ea17cFC"
|
||||
}
|
||||
}
|
||||
},
|
||||
"0x2719372560498ffc102f913621fdd11c668620634b0bd19ac99f4c1b67b4a7ff": {
|
||||
"contracts": {
|
||||
"0x1797453304e4b69b44fb7d649a72ca80394a8b4e1d14c2cc530f5dc3ae1f0ea3": {
|
||||
"name": "ENSRegistry",
|
||||
"address": "0x3a305F52947bDdb1663ba48229BcbC33238790d8"
|
||||
},
|
||||
"0x6a770cca5f266bae333e2c802b4f0710a548ccb64661907121279190a5e8cd2b": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x380F1cd84E746B792Aae796c62aC48783800475d"
|
||||
},
|
||||
"0x940f63055cb17182e1de6792164769bba2f02a4c663a79a8b1bdacb05dbfdef2": {
|
||||
"name": "DTwitter",
|
||||
"address": "0xc16e87a0716cAeF4560E36B2FfdaBfd0f74d4e17"
|
||||
},
|
||||
"0x8512591968343fa8314588a1194311ca6ba57650bae5085b1198f3508513fc09": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x0Fa5D598ad59B6Ad9936735C82697A2f12AB9309"
|
||||
},
|
||||
"0x7fc0f6d624bcbcaf4649145e39c9b642b05f87c9cd62a83e75b4167bf6280661": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0xC1eaF9904B3D0C2dA8fd8feCfFB58F524Caa4235"
|
||||
},
|
||||
"0xdbaf82c08d54eeed3a161922e9e9cf16acc9a031ecf00e66c1a6c9a7dfcb7470": {
|
||||
"name": "DTwitter",
|
||||
"address": "0x2Eaf83D1421238776568b5c0d6779dCae111d3B0"
|
||||
},
|
||||
"0x6d1e2e0bd96a493aaab99909e0fd4ed874e93edd9a58020916846e08876c3b01": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x6CcEa7207DF046dA53691F623EbA319D16b86cF9"
|
||||
},
|
||||
"0x0493e11c7d7363b628e1ecd882629c40096d4c05dd62aa0c6a6cff950e41829c": {
|
||||
"name": "DTwitter",
|
||||
"address": "0x782bB0785C0Fc0a19CD3f0AD6861e1E01355D497"
|
||||
},
|
||||
"0x82270912d9d3b43446636416c256f2fda79674a77417315ed6bb4620b52fe54b": {
|
||||
"name": "DTwitter",
|
||||
"address": "0x3838787BA50DbDEF323FF15dfC56F179FABb86c3"
|
||||
},
|
||||
"0x0639bcd42730e51cf5ecc22a06ffd7792fe85c3d774b8ba59f0d08829b914b16": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x3A5eaaeFdB48Dc7a5F8DF1a3b036296451233FD2"
|
||||
},
|
||||
"0x9069e55a1671e0d65292da254624454e1164d95a59b5054226444641dc5b7241": {
|
||||
"name": "DTwitter",
|
||||
"address": "0x9C65d2936E38F13210ba52Db2eA66113f403F0A4"
|
||||
},
|
||||
"0x4d7362a677446c5c3833b1f92c495c9a4ef102f5c89baecd8ee5c7dedda43bc0": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0xd6bb0D548Cc339e93303e839D2F31A0CB8e0C7Ed"
|
||||
},
|
||||
"0xf39de5ffc41b8c0cd27c9428411594ad4e93df94a4d8d200dff4d616ff2c2da6": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x6826F913EB5D5fC1b02832128DfFB51305050295"
|
||||
},
|
||||
"0xeef98a0087f598564ce46e90efb76c011dabe1aaaa42f2f058b7cf6aa7076a3d": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x466C87E7d667E142dE074e7B95de2Ac0ee840d55"
|
||||
},
|
||||
"0x9e01145e31f3e40a45b0a87e04f331d553433c01872b51cce608ec1e7a618f53": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x444eE0078C0eaDb191226845A8EFeA9920A1B3Ac"
|
||||
},
|
||||
"0xd90232b0ff53ce7e8f0f9f952727e5465d4a75883b55374a9285ef2c87487a74": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x63E87033f39A098a4D2778f74059b747c8Fa9b2e"
|
||||
},
|
||||
"0x87d94e2612fa834a9fdb8198d579a2b13d5e3bb55b077c744ffe9a60f85a494a": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x1Af8411262Bd7Bcd3653aBb81abAA3C4d3B67262"
|
||||
},
|
||||
"0x6111dd2ed21153ccfb4a0222c5afb3a40da7a1331876068d720d9eca1d127cff": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x874F6416a2751A9685942ceBad5724F6552363Ba"
|
||||
},
|
||||
"0xc07d9ab43515dc74fc1152d38bd21e18d669d74da0996fb5336084dfc3ced879": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x2551ECA589280510F52455A4c436A5c092750a57"
|
||||
},
|
||||
"0x8e9719440b59d6df083533898ef3ea6a77962dcb8ce81677aac7948ef0c20e34": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0xefc2913cA38Cc42a2c7e37d5b8772C38d8f3E6EE"
|
||||
},
|
||||
"0x24f84ae6b65cd098c258c29426edccff5dd244bf406691fc283b3a4d9a3c37c6": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x303d27c6f23A67e88Ea12eFdc763AaeD1Cc14a1c"
|
||||
},
|
||||
"0x3a721b7e56717bee6a4962e63d8288bbbdb3dca04559a9e4f9953e212dc0df48": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x538689FDBCDff43FF7DbD1a1bd32135986b48B7c"
|
||||
},
|
||||
"0x3a8831a9b9c58734d580907b3d9901e2dcf2085623a8374cb799fe728aa44457": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0xe6B9e1fE969B8Ae25d865bBAF5857D470d395A7c"
|
||||
},
|
||||
"0x4d366bd85cc54f5c4a83f6b40b3a3677310eb0dd34f389767d63387c27967a94": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x848DEd3483FC46943696FD5126fC6EBea606755C"
|
||||
},
|
||||
"0x306a442b9d884112f40feb96d7f7c6feedfcb5e3a22f7f0fb94e2707f705e9ae": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x8Dae7b46F857FbaB2b6CdB72E19F00c19E935e32"
|
||||
},
|
||||
"0x4106d6b2ac55d1b27a711efdc9958888872ea92150182b6acdbba71337ecb4b0": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0xaeF05E95a9911DDcd1C6a74bC5Ec5418f59D8721"
|
||||
},
|
||||
"0xfa425d3927a89290384086a8ee3094e79705d1efb5e26d9488b2afdef186b85a": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0x8Bb521a91a87bA2b45838b945f42bB38Eea75AfD"
|
||||
},
|
||||
"0xcc778f563e76137fa39d446d61c7eab7c4a0c7ff90022e952e7102cd393a5d7a": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0xD7C4419cF91C9B3D2d960339EC7BD9590b30D2aB"
|
||||
},
|
||||
"0x17e26bdacc4661c4eb3e1244d0a3f4989c2a25edd5305b89f2ffe844ce1344b1": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0xBB6599908d6a5e9B93da8D25eDA766e516a9dad4"
|
||||
},
|
||||
"0x848e86fb58f1f7768f1189a9d854c8dfef9da22ddeff9c61cd2e0fba36be8d7c": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0xdB823DCB3EB04b7A5d766F5001Ce007A2c2AE7fe"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,11 @@ contract DTwitter {
|
|||
users[usernameHash].description = description;
|
||||
}
|
||||
|
||||
function userExists(string username) public view returns (bool) {
|
||||
bytes32 usernameHash = keccak256(abi.encodePacked(username));
|
||||
return users[usernameHash].creationDate != 0;
|
||||
}
|
||||
|
||||
function updateProfilePicture(string username, string pictureHash) public {
|
||||
bytes32 usernameHash = keccak256(abi.encodePacked(username));
|
||||
require(users[usernameHash].owner == msg.sender);
|
||||
|
@ -56,7 +61,7 @@ contract DTwitter {
|
|||
|
||||
function getTweet(string username, uint index) public view returns(string retTweet) {
|
||||
bytes32 usernameHash = keccak256(abi.encodePacked(username));
|
||||
|
||||
require(users[usernameHash].creationDate != 0);
|
||||
return users[usernameHash].tweets[index];
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"contracts": ["app/contracts/**"],
|
||||
"contracts": ["contracts/**"],
|
||||
"app": {
|
||||
"css/app.css": ["app/css/**"],
|
||||
"js/app.js": ["app/js/_vendor/**", "app/js/**"],
|
||||
"js/app.js": ["app/js/**"],
|
||||
"index.html": "app/index.html"
|
||||
},
|
||||
"buildDir": "dist/",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
|
@ -1,18 +1,18 @@
|
|||
{
|
||||
"name": "DTwitter",
|
||||
"name": "app_name",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "Gruntfile.js",
|
||||
"scripts": {
|
||||
"test": "embark test"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"homepage": "",
|
||||
"devDependencies": {
|
||||
"embark": "^2.4.2",
|
||||
"mocha": "^2.2.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"jquery": "^3.3.1"
|
||||
"react": "^16.3.2",
|
||||
"react-bootstrap": "^0.32.1",
|
||||
"react-dom": "^16.3.2",
|
||||
"react-router-dom": "^4.2.2"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue