diff options
| -rw-r--r-- | bucky/app/bucky.js | 13 | ||||
| -rw-r--r-- | bucky/app/router.js | 52 | ||||
| -rw-r--r-- | package-lock.json | 22 | ||||
| -rw-r--r-- | package.json | 1 | ||||
| -rw-r--r-- | public/assets/css/bucky.css | 20 | ||||
| -rwxr-xr-x | public/assets/img/profile.jpg | bin | 0 -> 35057 bytes | |||
| -rw-r--r-- | public/assets/js/lib/router.js | 8 | ||||
| -rw-r--r-- | public/assets/js/lib/views/details/comments.js | 3 | ||||
| -rw-r--r-- | public/assets/js/lib/views/index/hootbox.js | 3 | ||||
| -rw-r--r-- | public/assets/js/lib/views/profile/profile.js | 8 | ||||
| -rw-r--r-- | public/assets/js/lib/views/profile/profile_edit.js | 50 | ||||
| -rw-r--r-- | public/assets/js/util/format.js | 3 | ||||
| -rw-r--r-- | views/pages/comment_form.ejs (renamed from views/pages/editcomment.ejs) | 0 | ||||
| -rw-r--r-- | views/pages/mailbox.ejs | 2 | ||||
| -rw-r--r-- | views/pages/message.ejs | 1 | ||||
| -rw-r--r-- | views/pages/profile.ejs | 2 | ||||
| -rw-r--r-- | views/pages/profile_form.ejs | 84 | ||||
| -rw-r--r-- | views/pages/search.ejs | 1 | ||||
| -rw-r--r-- | views/partials/comments.ejs | 2 | ||||
| -rw-r--r-- | views/partials/hootbox.ejs | 2 | ||||
| -rw-r--r-- | views/partials/scripts.ejs | 2 | ||||
| -rw-r--r-- | views/partials/threads.ejs | 2 |
22 files changed, 255 insertions, 26 deletions
diff --git a/bucky/app/bucky.js b/bucky/app/bucky.js index 2f17ffc..f3ea689 100644 --- a/bucky/app/bucky.js +++ b/bucky/app/bucky.js @@ -375,7 +375,7 @@ var bucky = module.exports = { }) }, - /* PROFILE */ + /* PROFILE / USER */ ensureUser: function (req, res, next){ var username = util.sanitizeName(req.params.username) @@ -396,9 +396,18 @@ var bucky = module.exports = { req.user.set('lastseen', util.now()) req.user.save().then( () => next() ) }, + updateUser: function(req, res, next) { + + }, /* PRIVACY */ - + + checkUserPrivacy: function(req, res, next) { + if (req.user.get('username') !== res.user.get('username')) { + return res.sendStatus(500) + } + next() + }, checkThreadPrivacy: function(req, res, next) { if (req.user.get('ulevel') !== 3 && req.user.get('username') !== res.thread.get('username')) { return res.sendStatus(500) diff --git a/bucky/app/router.js b/bucky/app/router.js index 7fbf479..0935f1a 100644 --- a/bucky/app/router.js +++ b/bucky/app/router.js @@ -49,22 +49,46 @@ module.exports = function(app){ } ) app.get("/comment/:id/edit", middleware.ensureAuthenticated, function(req, res){ - res.render("pages/editcomment", {title: "Edit comment"}) + res.render("pages/comment_form", {title: "Edit comment"}) }) app.get("/profile", middleware.ensureAuthenticated, function(req, res){ - res.render("pages/profile", {title: "profile: " + util.sanitize(req.user.get('username'))}) - } - ) + res.render("pages/profile", {title: "profile for " + util.sanitize(req.user.get('username'))}) + }) app.get("/profile/:username", middleware.ensureAuthenticated, function(req, res){ - res.render("pages/profile", {title: "profile: " + util.sanitize(req.params.username)}) + res.render("pages/profile", {title: "profile for " + util.sanitize(req.params.username)}) + }) + app.get("/profile/:username/edit", + middleware.ensureAuthenticated, + function(req, res){ + res.render("pages/profile_form", {title: "edit your profile"}) + }) + + /* users */ + + app.get("/api/user/:username", + middleware.ensureAuthenticated, + bucky.ensureUser, + function(req, res) { + res.json(res.user) } ) + app.post("/api/user/:username", + middleware.ensureAuthenticated, + bucky.ensureUser, + bucky.checkUserPrivacy, + multer.single("avatar"), + bucky.updateUser, + function(req, res){ + res.json(res.thread) + }) + /* threads */ + app.get("/api/index", bucky.ensureLastlog, middleware.ensureAuthenticated, @@ -81,14 +105,6 @@ module.exports = function(app){ lastlog: res.lastlog, }) }) - - app.get("/api/user/:username", - middleware.ensureAuthenticated, - bucky.ensureUser, - function(req, res) { - res.json(res.user) - } - ) app.get("/api/keyword/:keyword", bucky.ensureLastlog, middleware.ensureAuthenticated, @@ -150,7 +166,9 @@ module.exports = function(app){ function(req, res){ res.sendStatus(200) }) - + + /* comments */ + app.post("/api/thread/:id/comment", middleware.ensureAuthenticated, bucky.ensureThread, @@ -192,6 +210,8 @@ module.exports = function(app){ res.sendStatus(200) }) + /* search */ + app.get("/search/", middleware.ensureAuthenticated, function(req, res){ @@ -207,6 +227,8 @@ module.exports = function(app){ search.success ) + /* keywords */ + app.get("/api/keywords", middleware.ensureAuthenticated, bucky.ensureKeywords, @@ -228,6 +250,8 @@ module.exports = function(app){ threads: res.threads, }) }) + + /* mail */ app.get("/mail/", middleware.ensureAuthenticated, diff --git a/package-lock.json b/package-lock.json index 167694d..d834840 100644 --- a/package-lock.json +++ b/package-lock.json @@ -787,6 +787,14 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "0.4.19" + } + }, "errorhandler": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.4.3.tgz", @@ -1049,6 +1057,11 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", @@ -1368,6 +1381,15 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } + }, "node-uuid": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", diff --git a/package.json b/package.json index 08d0a34..53016be 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "multer": "^1.0.3", "multiparty": "^4.1.2", "mysql2": "^0.15.8", + "node-fetch": "^1.7.3", "node-uuid": "^1.4.8", "passport": "^0.3.0", "passport-local": "^1.0.0", diff --git a/public/assets/css/bucky.css b/public/assets/css/bucky.css index ce55bfa..a85ac21 100644 --- a/public/assets/css/bucky.css +++ b/public/assets/css/bucky.css @@ -96,6 +96,9 @@ input[type=password] { border: 1px solid #888; padding: 3px; } +input[type=file] { + cursor: pointer; +} #menu { margin: 7px 0 14px; } @@ -852,13 +855,26 @@ header .search_form { /* LOGIN */ -#login div, -#signup div { +#login form > div, +#signup form > div, +#profile_form form > div { margin: 2px; + display: flex; + flex-direction: row; } #login .errors { display: inline-block; } +#login label, +#signup label, +#profile_form label { + margin-top: 4px; +} +#profile_form #profile-pic-embed { + display: block; + margin-bottom: 5px; + max-width: 100px; +} /* 404 */ #error_404 { diff --git a/public/assets/img/profile.jpg b/public/assets/img/profile.jpg Binary files differnew file mode 100755 index 0000000..b8327bb --- /dev/null +++ b/public/assets/img/profile.jpg diff --git a/public/assets/js/lib/router.js b/public/assets/js/lib/router.js index 7b0fbb6..c16e58e 100644 --- a/public/assets/js/lib/router.js +++ b/public/assets/js/lib/router.js @@ -23,10 +23,11 @@ var SiteRouter = Router.extend({ "/comment/:id/edit": 'editComment', "/profile": 'profile', "/profile/:username": 'profile', + "/profile/:username/edit": 'editProfile', }, initialize: function(){ - $("#logout").click(() => this.logout()) + $(".logout").click(() => this.logout()) }, index: function(keyword){ @@ -82,6 +83,11 @@ var SiteRouter = Router.extend({ app.view.load(username || auth.user.username) }, + editProfile: function(username){ + app.view = new ProfileForm () + app.view.load(username || auth.user.username) + }, + compose: function(username){ app.view = new ComposeView () app.view.load(username) diff --git a/public/assets/js/lib/views/details/comments.js b/public/assets/js/lib/views/details/comments.js index 4c217a4..0c2cdcc 100644 --- a/public/assets/js/lib/views/details/comments.js +++ b/public/assets/js/lib/views/details/comments.js @@ -27,7 +27,8 @@ var CommentsView = FormView.extend({ parse: function(comment){ if (! comment.comment.length) return $('') var datetime = verbose_date(comment.date, true) - var t = this.template.replace(/{{username}}/g, comment.username) + var t = this.template.replace(/{{image}}/g, profile_image(comment.username)) + .replace(/{{username}}/g, comment.username) .replace(/{{id}}/g, comment.id) .replace(/{{comment}}/g, tidy_urls(comment.comment)) .replace(/{{date}}/g, datetime[0]) diff --git a/public/assets/js/lib/views/index/hootbox.js b/public/assets/js/lib/views/index/hootbox.js index 6be9596..85fd51e 100644 --- a/public/assets/js/lib/views/index/hootbox.js +++ b/public/assets/js/lib/views/index/hootbox.js @@ -23,7 +23,8 @@ var HootBox = FormView.extend({ }, parse: function(comment){ - var t = this.template.replace(/{{username}}/g, comment.username) + var t = this.template.replace(/{{username}}/g, profile_image(comment.username)) + .replace(/{{username}}/g, comment.username) .replace(/{{comment}}/g, tidy_urls(comment.comment, true)) return t }, diff --git a/public/assets/js/lib/views/profile/profile.js b/public/assets/js/lib/views/profile/profile.js index d8bc535..1b3e496 100644 --- a/public/assets/js/lib/views/profile/profile.js +++ b/public/assets/js/lib/views/profile/profile.js @@ -19,7 +19,13 @@ var ProfileView = View.extend({ $("body").removeClass('loading') var $table = this.$("table") var username = sanitize(user.username) - this.$("img").attr("src", "/data/profile/" + username + ".jpg") + var is_own_profile = (username === auth.user.username) + if (is_own_profile) { + $(".edit_profile a").attr("href", "/profile/" + username + "/edit") + } else { + $(".edit_profile").hide() + } + this.$("img").attr("src", profile_image(username)) var fields = "username realname phone location".split(" ").map((key) => { if (! user[key]) return; var t = this.template.replace(/{{key}}/, sanitize(key)) diff --git a/public/assets/js/lib/views/profile/profile_edit.js b/public/assets/js/lib/views/profile/profile_edit.js new file mode 100644 index 0000000..a6ff211 --- /dev/null +++ b/public/assets/js/lib/views/profile/profile_edit.js @@ -0,0 +1,50 @@ +var ProfileForm = FormView.extend({ + + el: "#profile_form", + + events: { + "change #profile-pic": 'changeProfilePic', + }, + + action: "/api/user", + method: "POST", + + initialize: function(){ + this.__super__.initialize.call(this) + this.template = this.$(".template").html() + }, + + load: function(username){ + console.log('hi') + this.action = "/api/user/" + username; + "realname location email phone website fb twitter".split(" ").forEach((field) => { + this.$('[name=' + field + ']').val( sanitize(auth.user[field]) ) + }) + if (! auth.user.pic) { + $("#profile-pic-embed").hide() + } else { + $("#profile-pic-embed").attr("src", sanitize(auth.user.pic)) + } + $("body").removeClass('loading') + }, + + changeProfilePic: function(){ + // $("#profile-pic-embed").show().attr("src", sanitize(auth.user.pic)) + }, + + validate: function(){ + var errors = [] + var title = this.$("[name=title]").val() + if (! title || ! title.length) { + errors.push("Please title your post.") + } + return errors.length ? errors : null + }, + + success: function(data){ + if (data.error) { + return alert(data.error) + } + window.location.href = "/details/" + data.id + } +})
\ No newline at end of file diff --git a/public/assets/js/util/format.js b/public/assets/js/util/format.js index fcc1df0..7dee404 100644 --- a/public/assets/js/util/format.js +++ b/public/assets/js/util/format.js @@ -217,6 +217,9 @@ function make_link(file){ } return file.filename } +function profile_image(username){ + return "//s3.amazonaws.com/i.asdf.us/bucky/data/profile/" + username + ".jpg" +} function make_thumb(file){ if (file.storage) { return "//s3.amazonaws.com/" + file.storage + "/bucky/data/" + file.thread + "/" + encodeURIComponent(file.filename) diff --git a/views/pages/editcomment.ejs b/views/pages/comment_form.ejs index 97a8402..97a8402 100644 --- a/views/pages/editcomment.ejs +++ b/views/pages/comment_form.ejs diff --git a/views/pages/mailbox.ejs b/views/pages/mailbox.ejs index 386e857..d06bd7a 100644 --- a/views/pages/mailbox.ejs +++ b/views/pages/mailbox.ejs @@ -1,8 +1,10 @@ <% include ../partials/header %> + <div class="subtitle"> <a href='/'>< Home</a> · <a href='/mail/compose'>New Message</a> </div> + <div id="content"> <h3 id="no_messages"> diff --git a/views/pages/message.ejs b/views/pages/message.ejs index d46b5fb..6a81d46 100644 --- a/views/pages/message.ejs +++ b/views/pages/message.ejs @@ -1,4 +1,5 @@ <% include ../partials/header %> + <div class="subtitle"> <a href='/'>< Home</a> · <a href='/mail/'>Inbox</a> diff --git a/views/pages/profile.ejs b/views/pages/profile.ejs index 79260e9..86c17f6 100644 --- a/views/pages/profile.ejs +++ b/views/pages/profile.ejs @@ -1,7 +1,7 @@ <% include ../partials/header %> <div class="subtitle"> - <a href="/">< Home</a> + <a href="/">< Home</a> <span class="edit_profile">· <a href="">Edit Profile</a></span> </div> <div id="profile"> diff --git a/views/pages/profile_form.ejs b/views/pages/profile_form.ejs new file mode 100644 index 0000000..01b0fae --- /dev/null +++ b/views/pages/profile_form.ejs @@ -0,0 +1,84 @@ +<% include ../partials/header %> + +<div class="subtitle"> + <a href="/">< Home</a> · <a href="/profile">View profile</a></span> +</div> + +<div id="content"> + +<div id="profile_form"> + <form> + <div> + <label for="profile-realname">Real name</label> + <input type="text" id="profile-realname" name="realname"> + </div> + + <div> + <label for="profile-location">Location</label> + <input type="text" id="profile-location" name="location"> + </div> + + <div> + <label for="profile-email">Email address</label> + <input type="text" id="profile-email" name="email"> + </div> + + <div> + <label for="profile-phone">Phone</label> + <input type="text" id="profile-phone" name="phone"> + </div> + <br> + + <div> + <label for="profile-pic">Profile picture</label> + <div> + <img id="profile-pic-embed" /> + <input type="file" id="profile-pic" name="pic"> + </div> + </div> + <br> + + <div> + <label for="profile-webpage">Website</label> + <input type="text" id="profile-webpage" name="webpage"> + </div> + + <div> + <label for="profile-fb">Facebook</label> + <input type="text" id="profile-fb" name="fb"> + </div> + + <div> + <label for="profile-tw">Twitter</label> + <input type="text" id="profile-tw" name="tw"> + </div> + <br> + + <div> + <label for="profile-password">Change password?</label> + <input type="password" id="profile-password" name="password"> + </div> + + <div> + <label for="profile-password2">again:</label> + <input type="password" id="profile-password2" name="password2"> + </div> + <br> + + <div> + <label for="profile-submit"></label> + <button id="profile-submit">SAVE PROFILE</button> + </div> + + <br> + <div> + <label></label> + <span class="errors"> </span> + </div> + + </form> +</div> + +</div> + +<% include ../partials/footer %> diff --git a/views/pages/search.ejs b/views/pages/search.ejs index b942621..d830682 100644 --- a/views/pages/search.ejs +++ b/views/pages/search.ejs @@ -1,4 +1,5 @@ <% include ../partials/header %> + <div class="subtitle"> <a href="/">< Home</a> </div> diff --git a/views/partials/comments.ejs b/views/partials/comments.ejs index 907040f..b47702c 100644 --- a/views/partials/comments.ejs +++ b/views/partials/comments.ejs @@ -2,7 +2,7 @@ <script class="template" type="text/html"> <tr> <td class="user"> - <a href="/profile/{{username}}"><div class="avatar" style="background-image:url(/data/profile/{{username}}.jpg)"></div></a> + <a href="/profile/{{username}}"><div class="avatar" style="background-image:url({{image}})"></div></a> <a href="/profile/{{username}}">{{username}}</a> </td> <td colspan="2" class="comment"> diff --git a/views/partials/hootbox.ejs b/views/partials/hootbox.ejs index 0f6fce4..fe0298b 100644 --- a/views/partials/hootbox.ejs +++ b/views/partials/hootbox.ejs @@ -7,7 +7,7 @@ <table id="hoots"> <script class="template" type="text/html"> <tr> - <td class="avatar" style="background-image:url(/data/profile/{{username}}.jpg)"><a href="/profile/{{username}}"></a></td> + <td class="avatar" style="background-image:url({{image}})"><a href="/profile/{{username}}"></a></td> <td> {{comment}} </td> diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index 9563442..e80bdda 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -26,7 +26,9 @@ <script src="/assets/js/lib/views/index/threadform.js"></script> <script src="/assets/js/lib/views/search/results.js"></script> + <script src="/assets/js/lib/views/profile/profile.js"></script> +<script src="/assets/js/lib/views/profile/profile_edit.js"></script> <script src="/assets/js/lib/views/details/index.js"></script> <script src="/assets/js/lib/views/details/settings.js"></script> diff --git a/views/partials/threads.ejs b/views/partials/threads.ejs index 5c8e8a5..e429219 100644 --- a/views/partials/threads.ejs +++ b/views/partials/threads.ejs @@ -10,7 +10,7 @@ <a href="/post/">Start a new thread!</a> | <a href="/mail">Inbox</a> | <a href="/profile">Profile</a> | - <a href="/logout">Logout</a> + <a href="/logout" class="logout">Logout</a> </td> </tr> </script> |
