diff options
Diffstat (limited to 'public')
| -rw-r--r-- | public/assets/css/bucky.css | 79 | ||||
| -rw-r--r-- | public/assets/js/lib/router.js | 14 | ||||
| -rw-r--r-- | public/assets/js/lib/views/details/comments.js | 8 | ||||
| -rw-r--r-- | public/assets/js/lib/views/details/files.js | 5 | ||||
| -rw-r--r-- | public/assets/js/lib/views/keywords/keywords.js | 13 | ||||
| -rw-r--r-- | public/assets/js/lib/views/users/users.js | 88 | ||||
| -rw-r--r-- | public/assets/js/util/color.js | 16 | ||||
| -rw-r--r-- | public/assets/js/util/format.js | 57 |
8 files changed, 243 insertions, 37 deletions
diff --git a/public/assets/css/bucky.css b/public/assets/css/bucky.css index 9c9aa8a..bc35ddd 100644 --- a/public/assets/css/bucky.css +++ b/public/assets/css/bucky.css @@ -7,6 +7,7 @@ html { min-height: 100%; margin: 0; padding: 0; + margin-bottom: 150px; } body { min-width: 100%; @@ -17,7 +18,7 @@ body { font-size: 10px; font-family: Trebuchet MS, Helvetica, Arial, sans-serif; margin: 0; - padding: 20px 30px 200px 30px; + padding: 20px 30px 30px 30px; transition: opacity 100ms; } body.loading { @@ -507,6 +508,15 @@ code br, pre br { display: none; } +tt, kbd { + max-width: 580px; + display: inline-block; + font-family: Menlo, monospace; + background: #fefefe; + border: 1px solid #ddd; + padding: 2px; + font-size: 11px; +} #thread_form form { width: 530px; @@ -1244,3 +1254,70 @@ audio { padding-right: 2px; } } +@media (prefers-color-scheme: dark) { + body { + background: #180808; + color: #f8f8f8; + } + button:not(.hoot), input[type=submit] { + color: #f8f8f8; + border: 2px #eee solid; + padding: 2px; + margin: 3px; + background-color: #18202c; + text-transform: uppercase; + cursor: pointer; + } + .desktop button:not(.hoot):hover, + .desktop input[type=submit] { + color: #fff; + background-color: #28303c; + } + hr { + border-color: #fff; + } + a.headline:link, + a.headline:visited { color: #eee; text-decoration: none; } + .desktop a.headline:hover { color: #fff; text-decoration: none; } + .ledger .row td:nth-child(1) a { color: #ddd; } + #threads .keyword td a { color: #ddd; text-decoration: none; } + .desktop #threads .keyword td a:hover { color: #fff; text-decoration: underline; } + #threads .keyword td b a { color: #ddd; } + .desktop #threads .keyword td b a:hover { color: #fff; } + .subtitle a { color: #eee; text-decoration: none; } + .desktop.subtitle a:hover { color: #fff; text-decoration: underline; } + .ledger .new { color: #ffffff; font-weight: bold; } + .ledger .recent { color: #f8f0f0; } + .ledger .med { color: #e8e0e0; } + .ledger .old { color: #d8d0d0; } + .ledger .older { color: #b8b0b0; } + .ledger .quiet { color: #a7a4a4; } + + .files .new { color: #000000; } + .files .recent { color: #001111; } + .files .med { color: #203838; } + .files .old { color: #425050; } + .files .older { color: #5D6464; } + .files .quiet { color: #787878; } + .files .total a { color: #fff; } + + .bluebox { box-shadow: 0 0px 1.5px rgba(238,238,255,1.0), 0 0px 1.5px rgba(238,238,255,1.0); } + .search_form input[type='text']:focus { + border-bottom-color: #888; + } + .search_form input[type='text']:invalid { + caret-color: #888; + } + #comment_form textarea.empty { + border-bottom-color: #fff; + } + #comment_form textarea.empty::placeholder { + color: #fff; + } + #search { + color: #eee; + } + #search b { + color: #fff; + } +} diff --git a/public/assets/js/lib/router.js b/public/assets/js/lib/router.js index b6eff73..ebdfa78 100644 --- a/public/assets/js/lib/router.js +++ b/public/assets/js/lib/router.js @@ -22,7 +22,9 @@ var SiteRouter = Router.extend({ "/mail/compose/:username": 'compose', "/mail/read/:id": 'message', "/mail/reply/:id": 'compose', - "/profile": 'profile', + "/users": 'users', + "/users/all": 'usersAll', + "/profile": 'profile', "/profile/:username": 'profile', "/profile/:username/edit": 'editProfile', "/adminz": 'adminz', @@ -85,6 +87,16 @@ var SiteRouter = Router.extend({ app.view.load(keyword || "") }, + users: function(username){ + app.view = new UsersView () + app.view.load() + }, + + usersAll: function(username){ + app.view = new UsersView ({ all: true }) + app.view.load() + }, + profile: function(username){ app.view = new ProfileView () app.view.load(username || auth.user.username) diff --git a/public/assets/js/lib/views/details/comments.js b/public/assets/js/lib/views/details/comments.js index b1c86bb..1e8d127 100644 --- a/public/assets/js/lib/views/details/comments.js +++ b/public/assets/js/lib/views/details/comments.js @@ -14,8 +14,8 @@ var CommentsView = FormView.extend({ this.$formRow = this.$("#comment_form") }, - load: function(comments, thread){ -console.log(comments) + load: function(comments, thread) { + // console.log(comments) thread = this.thread = thread || this.thread if (thread.settings.hootbox) { comments @@ -35,13 +35,13 @@ console.log(comments) } }, - parse: function(comment){ + parse: function(comment) { if (! comment.comment.length) return $('') var datetime = verbose_date(comment.date, true) 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(/{{comment}}/g, function(){ return tidy_urls(comment.comment) }) .replace(/{{date}}/g, datetime[0]) .replace(/{{time}}/g, datetime[1]) var $t = $(t) diff --git a/public/assets/js/lib/views/details/files.js b/public/assets/js/lib/views/details/files.js index 44c65c4..98b9350 100644 --- a/public/assets/js/lib/views/details/files.js +++ b/public/assets/js/lib/views/details/files.js @@ -171,10 +171,15 @@ var FilesView = FormView.extend({ if (dateClass && this.reverse) { dateClass += ' italic' } + var sizeClass = this.sort === 'size' ? 'bold' : '' + if (sizeClass && this.reverse) { + sizeClass += ' italic' + } var t = this.templateTotal.replace(/{{size_class}}/g, size[0]) .replace(/{{size}}/g, size[1]) .replace(/{{nameClass}}/g, nameClass) .replace(/{{dateClass}}/g, dateClass) + .replace(/{{sizeClass}}/g, sizeClass) this.$el.append(t) }, diff --git a/public/assets/js/lib/views/keywords/keywords.js b/public/assets/js/lib/views/keywords/keywords.js index 12bd5a8..c5a9491 100644 --- a/public/assets/js/lib/views/keywords/keywords.js +++ b/public/assets/js/lib/views/keywords/keywords.js @@ -19,16 +19,21 @@ var KeywordsView = View.extend({ populate: function(data){ // console.log(data) var keywordThreads = {} - data.threadGroups.forEach(kw => { + var keywordStats = {} + data.threads.forEach(kw => { keywordThreads[kw.keyword] = kw }) + data.threadGroups.forEach(kw => { + keywordStats[kw.keyword] = kw + }) data.keywords .map(a => [parseInt((keywordThreads[a.keyword] || {})['sum(`viewed`)']) || 0, a]) .sort((b,a) => cmp(a[0], b[0])) .map(a => a[1]) .forEach(keyword => { var thread = keywordThreads[keyword.keyword.toLowerCase()] || { - title: '', + } + var stats = keywordStats[keyword.keyword.toLowerCase()] || { } // { // keyword: "warez", @@ -38,9 +43,9 @@ var KeywordsView = View.extend({ // lastmodified: 1192401724 // }, // console.log(keyword, thread) - var viewed = thread['sum(`viewed`)'] + var viewed = stats['sum(`viewed`)'] var views = viewed ? hush_views(viewed) : ['',''] - var threadCountNum = thread['count(*)'] + var threadCountNum = stats['count(*)'] var threadCount = threadCountNum ? hush_threads(threadCountNum) : ['',''] var dot = privacy_dot(thread.privacy) var datetime = verbose_date(keyword.createdate) diff --git a/public/assets/js/lib/views/users/users.js b/public/assets/js/lib/views/users/users.js new file mode 100644 index 0000000..b7e6450 --- /dev/null +++ b/public/assets/js/lib/views/users/users.js @@ -0,0 +1,88 @@ +var UsersView = View.extend({ + + el: "#user_list", + + events: { + }, + + action: "/api/users", + + initialize: function(opt){ + opt = opt || {} + this.showAll = !!opt.all + this.template = this.$(".template").html() + this.form = new NewKeywordForm ({ parent: this }) + if (!this.showAll) { + $('.all_link').attr('href', '/users/all').html('Show all users') + } else { + $('.all_link').attr('href', '/users').html('Show active users') + } + }, + + load: function(){ + $.get(this.action, this.populate.bind(this)) + }, + + populate: function(data){ + console.log(data) + // var keywordThreads = {} + // data.threadGroups.forEach(kw => { + // keywordThreads[kw.keyword] = kw + // }) + var showAll = this.showAll + var userStats = data.userStats + data.users + // .map(a => [parseInt((keywordThreads[a.keyword] || {})['sum(`viewed`)']) || 0, a]) + // .sort((b,a) => cmp(a[0], b[0])) + // .map(a => a[1]) + .map(user => { + // var user = users[user.username.toLowerCase()] || return + // var viewed = thread['sum(`viewed`)'] + // var views = viewed ? hush_views(viewed) : ['',''] + // var threadCountNum = thread['count(*)'] + // var threadCount = threadCountNum ? hush_threads(threadCountNum) : ['',''] + // "id", "username", "realname", "firstseen", "lastseen", + // "location", "website", "avatar", + var stats = userStats[user.username] || {} + if (!showAll && !stats.threads && !stats.files && !stats.comments) { + return + } + var threadCount = stats.threads ? hush_threads(stats.threads) : ['',''] + var fileCount = stats.files ? hush_null(stats.files, 'f') : ['',''] + var fileSize = stats.files ? hush_size(stats.fileSize) : ['',''] + var commentCount = stats.comments ? hush_null(stats.comments, 'c') : ['',''] + var firstseen_datetime = verbose_date(user.firstseen) + var lastseen = get_age(user.lastseen, true) + var avatar = profile_image(user.username) + var t = this.template + .replace(/{{username}}/g, sanitizeHTML(user.username)) + .replace(/{{id}}/g, user.id) + .replace(/{{avatar}}/g, user.avatar) + .replace(/{{location}}/g, sanitizeHTML(user.location)) + .replace(/{{realname}}/g, sanitizeHTML(user.realname)) + .replace(/{{firstseen_date}}/g, firstseen_datetime[0]) + .replace(/{{firstseen_time}}/g, firstseen_datetime[1]) + .replace(/{{firstseen_date_class}}/g, carbon_date(user.firstseen) ) + .replace(/{{lastseen}}/g, lastseen ) + .replace(/{{lastseen_date_class}}/g, carbon_date(lastseen) ) + .replace(/{{threadcount}}/, threadCount[1]) + .replace(/{{threadcount_class}}/, threadCount[0]) + .replace(/{{filecount}}/, fileCount[1]) + .replace(/{{filecount_class}}/, fileCount[0]) + .replace(/{{filesize}}/, fileSize[1]) + .replace(/{{filesize_class}}/, fileSize[0]) + .replace(/{{commentcount}}/, commentCount[1]) + .replace(/{{commentcount_class}}/, commentCount[0]) + var $t = $(t) + if (!user.firstseen) { + $t.find('.date').html('') + } + // if (!user.avatar) { + // $t.find('.avatar').addClass('hidden') + // } + this.$el.append($t) + }) + $("body").removeClass('loading') + }, + +}) diff --git a/public/assets/js/util/color.js b/public/assets/js/util/color.js index 6d33a72..ec21925 100644 --- a/public/assets/js/util/color.js +++ b/public/assets/js/util/color.js @@ -65,6 +65,19 @@ var COLORS = { black: new Color(32,32,37), } +var DARK_COLORS = { + plain: new Color(24,10,10), + ivory: new Color(18,18,18), + pink: new Color(40,23,35), + red: new Color(40,24,23), + orange: new Color(40,32,23), + yellow: new Color(40,40,31), + green: new Color(33,40,31), + blue: new Color(24,26,40), + purple: new Color(35,31,40), + black: new Color(0,0,0), +} + function nighttime_quotient() { var q = -10; var date = new Date() @@ -111,7 +124,8 @@ function set_background_color_from_time(){ } function set_background_color(color_name){ color_name = color_name || "plain" - var color = COLORS[color_name] + var color_set = window.matchMedia('(prefers-color-scheme: dark)').matches ? DARK_COLORS : COLORS + var color = color_set[color_name] .clone() .mottleRGB(4,4,8) // .add(nighttime_quotient()) diff --git a/public/assets/js/util/format.js b/public/assets/js/util/format.js index b04c056..d868ddd 100644 --- a/public/assets/js/util/format.js +++ b/public/assets/js/util/format.js @@ -23,19 +23,20 @@ function querystring(opt){ }).join("&") } function commatize (n, radix) { - radix = radix || 1024 + radix = radix || 1000 var nums = [], i, counter = 0, r = Math.floor - if (n > radix) { + if (radix !== -1 && n > radix) { n /= radix nums.unshift(r((n * 10) % 10)) nums.unshift(".") } do { - i = n % 10 + i = r(n % 10) n = r(n / 10) - if (n && ! (++counter % 3)) + counter += 1 + if (n && ! (counter % 3)) { i = ' ' + r(i) } - nums.unshift(r(i)) + nums.unshift(i) } while (n) return nums.join("") @@ -102,14 +103,14 @@ function hush_views (n, bias, no_bold) { n = n || 0 if (n < 30) { return["quiet", n + " v."] } if (n < 200) { return ["quiet", txt + " v."] } - else if (n < 500) { return ["quiet", txt + " v."] } - else if (n < 1000) { return ["old", txt + " v."] } - else if (n < 5000) { return ["med", txt + " kv."] } + else if (n < 500) { return ["old", txt + " v."] } + else if (n < 1000) { return ["med", txt + " v."] } + else if (n < 5000) { return ["recent", txt + " kv."] } else if (no_bold || n < 10000) { return ["recent", txt + " kv."] } else { return ["new", txt + " kv."] } } function hush_threads (n, bias, no_bold) { - var txt = commatize(n, 1000) + var txt = commatize(n, -1) bias = bias || 1 n = n || 0 if (n < 10) { return["quiet", n + " t."] } @@ -120,33 +121,37 @@ function hush_threads (n, bias, no_bold) { } function hush_size (n, bias, no_bold) { - var txt = commatize(Math.floor(n / 1024)) + var txt = commatize(Math.floor(n / 1024), 1000) bias = 1 || bias n = n || 0 if (n < 1024) { return ["quiet", n + " b."] } - if (n < 1024*1024) { + if (n < 1000*1000) { return ["quiet", txt + " kb."] } - else if (n < (20000000/bias)) { + if (n < (20000000/bias)) { return ["quiet", txt + " mb."] } - else if (n < (50000000/bias)) { + if (n < (50000000/bias)) { return ["old", txt + " mb."] } - else if (n < (80000000/bias)) { + if (n < (80000000/bias)) { return ["med", txt + " mb."] } - else if (no_bold || n < (170000000/bias)) { + if (no_bold || n < (170000000/bias)) { return ["recent", txt + " mb."] } - else { - return ["new", txt + " mb."] + if (n >= 10000*1000*1000) { + console.log(n) + txt = commatize(Math.floor(n / (1024 * 1024 * 1024))) + return ["new", txt + " gb."] } + return ["new", txt + " mb."] } function hush_null (n, unit, no_bold) { + n = commatize(n, -1) var s = unit ? n + " " + unit + "." : n if (n < 3) { return ["quiet", s] @@ -185,26 +190,26 @@ function get_revision (thread) { return digits } -function get_age (t) { +function get_age (t, long) { var age = Math.abs( Date.now()/1000 - t) var r = Math.floor var m if (age < 5) { return "now" } - if (age < 60) { return r(age) + "s" } + if (age < 60) { return r(age) + (long ? ' seconds' : "s") } age /= 60 - if (age < 60) { return r(age) + "m" } + if (age < 60) { return r(age) + (long ? ' minutes' : "m") } m = r(age % 60) age /= 60 - if (m > 0 && age < 2) { return r(age) + "h" + m + "m" } - if (age < 24) { return r(age) + "h" } + if (m > 0 && age < 2) { return r(age) + (long ? ' hours ' + m + ' minutes' : "h" + m + "m") } + if (age < 24) { return r(age) + (long ? ' hours' : "h") } age /= 24 - if (age < 7) { return r(age) + "d" } + if (age < 7) { return r(age) + (long ? ' days' : "d") } age /= 7 - if (age < 12) { return r(age) + "w" } + if (age < 12) { return r(age) + (long ? ' weeks' : "w") } age /= 4 - if (age < 12) { return r(age) + "m" } + if (age < 12) { return r(age) + (long ? ' months' : "m") } age /= 12 - return r(age) + "y" + return r(age) + (long ? ' years' : "y") } function tidy_urls (s, short_urls) { |
