Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repost feature #2

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions css/all.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion css/icons.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
padding-left: 32px; padding-right: 2px; background-position: 7px 5px;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASBAMAAACp/uMjAAAAMFBMVEUAAACqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqobnPPZAAAAD3RSTlMADcS4pt/IwK9qXE9ELRXt9n51AAAAaElEQVQI12PABRhtGRguC4CZQl8f8MUrggX1/yeK/f8kABL8//+L////imBBEAAJM/+HAgMGHhjzAAPDfgjrN1AbF4S5AGTafBDrJ9gKFhDTAWJz////P6COYAaZBAX13+FuY1JAcywAx1BERa6oCoIAAAAASUVORK5CYII=')
}
.icon-heart.active { color: #5d68ff; filter: sepia(1) hue-rotate(192deg) brightness(0.55) saturate(5) }
.icon-heart.active, .icon-share.active { color: #5d68ff; filter: sepia(1) hue-rotate(192deg) brightness(0.55) saturate(5) }

.icon-up { font-weight: normal !important; font-size: 15px; font-family: Tahoma; vertical-align: -4px; padding-right: 5px; display: inline; height: 1px; }
.icon-upload {
Expand Down
18 changes: 16 additions & 2 deletions dbschema.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
".+/data/users/.+/data.json": {
"to_table": [
"post",
"repost",
"comment",
"follow",
{"node": "post_like", "table": "post_like", "key_col": "post_uri", "val_col": "date_added"}
Expand All @@ -39,18 +40,31 @@
["avatar", "TEXT"]
],
"indexes": ["CREATE UNIQUE INDEX path ON json(directory, site, file_name)"],
"schema_changed": 4
"schema_changed": 5
},
"post": {
"cols": [
["post_id", "INTEGER"],
["body", "TEXT"],
["repost_uri", "TEXT"],
["meta", "TEXT"],
["date_added", "INTEGER"],
["json_id", "INTEGER REFERENCES json (json_id)"]
],
"indexes": ["CREATE UNIQUE INDEX post_key ON post(json_id, post_id)", "CREATE INDEX post_id ON post(post_id)", "CREATE INDEX added ON post(date_added)"],
"schema_changed": 4
"schema_changed": 5
},
"repost": {
"cols": [
["post_id", "INTEGER"],
["body", "TEXT"],
["repost_uri", "TEXT"],
["meta", "TEXT"],
["date_added", "INTEGER"],
["json_id", "INTEGER REFERENCES json (json_id)"]
],
"indexes": ["CREATE UNIQUE INDEX repost_key ON repost(json_id, post_id)", "CREATE INDEX repost_id ON repost(post_id)", "CREATE INDEX repost_added ON repost(date_added)"],
"schema_changed": 5
},
"post_like": {
"cols": [
Expand Down
47 changes: 44 additions & 3 deletions js/Post.coffee
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
class Post extends Class
constructor: (row, @item_list) ->
@liked = false
@reposted = false
@is_repost = false
@reposted_by = ""
@commenting = false
@submitting_like = false
@owned = false
Expand All @@ -16,8 +19,13 @@ class Post extends Class
@row = row
if @row.meta
@meta = new PostMeta(@, JSON.parse(@row.meta))
@is_repost = row["is_repost"]
if Page.user
@liked = Page.user.likes[@row.key]
@liked = Page.user.likes[@row.post_uri]
if (Page.user.reposts)
@reposted = Page.user.reposts[@row.post_uri]
if @is_repost
@reposted_by = new User({hub: row.reposted_by_hub, auth_address: row.reposted_by_directory.replace("data/users/", "")})
@user = new User({hub: row.site, auth_address: row.directory.replace("data/users/", "")})
@user.row = row
@owned = @user.auth_address == Page.user?.auth_address
Expand Down Expand Up @@ -63,6 +71,28 @@ class Post extends Class
@follow()
return false

handleRepostClick: (e) =>
@submitting_repost = true
if @row.is_repost
site = @row.site
post_uri = @row.post_uri
else
[site, post_uri] = @row.key.split("-")

# reposted = Page.user?.reposts[post_uri] | Page.user?.reposts[@row.post_uri]

if Page.user.reposts[post_uri]
Animation.flashOut(e.currentTarget.firstChild)
Page.user.derepost post_uri, =>
@submitting_repost = false
@unfollow()
else
Animation.flashIn(e.currentTarget.firstChild)
Page.user.repost post_uri, =>
@submitting_repost = false
@follow()
return false

handleCommentClick: =>
if @field_comment.node
@field_comment.node.focus()
Expand Down Expand Up @@ -217,8 +247,10 @@ class Post extends Class

render: =>
[site, post_uri] = @row.key.split("-")
if Page.user and Page.user.reposts
reposted = Page.user?.reposts[post_uri] | Page.user?.reposts[@row.post_uri]
h("div.post", {key: @row.key, enterAnimation: Animation.slideDown, exitAnimation: Animation.slideUp, animate_scrollfix: true, classes: {selected: @row.selected}, style: @css_style}, [
h("div.user", [
h("div.user", {style: if @is_repost then "height: unset;" else ""}, [ # TODO: use CSS classes
@user.renderAvatar({href: @user.getLink(), onclick: Page.handleLinkClick}),
h("a.name.link", {href: @user.getLink(), onclick: Page.handleLinkClick, style: "color: #{Text.toColor(@user.auth_address)}"},
@row.user_name
Expand All @@ -229,6 +261,12 @@ class Post extends Class
h("a.added.link", {href: @getLink(), title: Time.date(@row.date_added, "long"), onclick: Page.handleLinkClick}, Time.since(@row.date_added)),
if @menu then @menu.render(".menu-right"),
h("a.settings", {href: "#Settings", onclick: Page.returnFalse, onmousedown: @handleSettingsClick}, "\u22EE")
if @is_repost then h("div", {style: "opacity: 75%; font-sie: 14px;" }, [
h("div.icon.icon-share", {style: "margin-left: -10px; margin-top: -4px;"}),
"Reposted by ",
@reposted_by.renderAvatar({href: @reposted_by.getLink(), onclick: Page.handleLinkClick, small: true})],
"#{@row.reposted_by_address}"
),
])
if @owned
@editable_body.render(@row.body)
Expand All @@ -242,7 +280,10 @@ class Post extends Class
h("div.icon.icon-heart", {classes: {active: Page.user?.likes[post_uri]}}),
if @row.likes then @row.likes
)
# h("a.icon.icon-share.link", {href: "#Share"}, "Share"),
h("a.repost.link", {classes: {active: reposted, loading: @submitting_repost, "repost-zero": @row.reposts == 0}, href: "#Repost", onclick: @handleRepostClick},
h("div.icon.icon-share", {classes: {active: reposted}}),
if @row.reposts then @row.reposts
)
]),
@renderComments()
])
Expand Down
135 changes: 101 additions & 34 deletions js/PostList.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,35 @@ class PostList extends Class
query = "SELECT post_uri, COUNT(*) AS likes FROM post_like WHERE ? GROUP BY post_uri"
return Page.cmd "dbQuery", [query, {post_uri: post_uris}], cb

queryReposts: (post_uris, cb) =>
query = "SELECT repost_uri AS post_uri, COUNT(*) AS reposts FROM repost WHERE ? GROUP BY repost_uri"
return Page.cmd "dbQuery", [query, {post_uri: post_uris}], cb

queryRepostOrigin: (reposts_origins, cb) =>
post_directories = []
post_ids = []

for item in reposts_origins
do (item) ->
post_directories.push("data/users/" + item.repost_uri.split('_')[0])
post_ids.push(item.repost_uri.split('_')[1])

query = "
SELECT * FROM post
LEFT JOIN json ON (post.json_id = json.json_id)
WHERE
post_id IN #{Text.sqlIn(post_ids)} AND directory IN #{Text.sqlIn(post_directories)}
"
return Page.cmd "dbQuery", [query], cb

update: =>
@need_update = false

param = {}
if @directories == "all"
where = "WHERE post_id IS NOT NULL AND post.date_added < #{Time.timestamp()+120} "
where = "WHERE post_id IS NOT NULL AND date_added < #{Time.timestamp()+120} "
else
where = "WHERE directory IN #{Text.sqlIn(@directories)} AND post_id IS NOT NULL AND post.date_added < #{Time.timestamp()+120} "
where = "WHERE directory IN #{Text.sqlIn(@directories)} AND post_id IS NOT NULL AND date_added < #{Time.timestamp()+120} "

if @filter_post_ids
where += "AND post_id IN #{Text.sqlIn(@filter_post_ids)} "
Expand All @@ -41,53 +62,99 @@ class PostList extends Class
where += "AND post_id > 1 "

query = "
SELECT
*
FROM
post
SELECT * FROM post
LEFT JOIN json ON (post.json_id = json.json_id)
#{where}

UNION ALL

SELECT * FROM repost
LEFT JOIN json ON (repost.json_id = json.json_id)
#{where}

ORDER BY date_added DESC
LIMIT #{@limit+1}
"
@logStart "Update"
Page.cmd "dbQuery", [query, param], (rows) =>
items = []
post_uris = []
for row in rows
reposts_origins = {}

for row, i in rows
row["key"] = row["site"]+"-"+row["directory"].replace("data/users/", "")+"_"+row["post_id"]
row["post_uri"] = row["directory"].replace("data/users/", "") + "_" + row["post_id"]
post_uris.push(row["post_uri"])

# Get comments for latest posts

@queryComments post_uris, (comment_rows) =>
comment_db = {} # {Post id: posts}
for comment_row in comment_rows
comment_db[comment_row.site+"/"+comment_row.post_uri] ?= []
comment_db[comment_row.site+"/"+comment_row.post_uri].push(comment_row)
for row in rows
row["comments"] = comment_db[row.site+"/"+row.post_uri]
if @filter_post_ids?.length == 1 and row.post_id == parseInt(@filter_post_ids[0])
row.selected = true
@item_list.sync(rows)
@loaded = true
@logEnd "Update"
Page.projector.scheduleRender()

if @posts.length > @limit
@addScrollwatcher()

@queryLikes post_uris, (like_rows) =>
like_db = {}
for like_row in like_rows
like_db[like_row["post_uri"]] = like_row["likes"]
if row["repost_uri"] and row["repost_uri"] != null
reposts_origins[row["repost_uri"]] = row
reposts_origins[row["repost_uri"]].repost_id = i
else
post_uris.push(row["post_uri"])

# Fetch original posts from reposts (get original bodies and other data by "repost_uri" from repost).
# Repost doesn't contains post body (it have only uri to origin).

@queryRepostOrigin Object.values(reposts_origins), (repost_origin_rows) =>
repost_origin_db = {}

for row in repost_origin_rows
row["key"] = row["site"]+"-"+row["directory"].replace("data/users/", "")+"_"+row["post_id"]
row["post_uri"] = row["directory"].replace("data/users/", "") + "_" + row["post_id"]
repost = reposts_origins[row["post_uri"]]

# Put some metadata from repost (eg. who did this repost)
row["is_repost"] = true
row["key"] = repost.key
row["reposted_by_hub"] = repost["hub"]
row["reposted_by_directory"] = repost["directory"]
row["reposted_by_address"] = repost["cert_user_id"]
row["repost_uri"] = repost["post_uri"]
rows[repost.repost_id] = row

post_uris.push(row["post_uri"])

for row in rows
row["likes"] = like_db[row["post_uri"]]
@item_list.sync(rows)
Page.projector.scheduleRender()

# Query comments, likes and reposts count only after quering reposts origins,
# because we want to retrieve this info from the original post (not from the repost itself).

# Get comments for latest posts
@queryComments post_uris, (comment_rows) =>
comment_db = {} # {Post id: posts}
for comment_row in comment_rows
comment_db[comment_row.site+"/"+comment_row.post_uri] ?= []
comment_db[comment_row.site+"/"+comment_row.post_uri].push(comment_row)
for row in rows
row["comments"] = comment_db[row.site+"/"+row.post_uri]
if @filter_post_ids?.length == 1 and row.post_id == parseInt(@filter_post_ids[0])
row.selected = true
@item_list.sync(rows)
@loaded = true
@logEnd "Update"
Page.projector.scheduleRender()

if @posts.length > @limit
@addScrollwatcher()

@queryLikes post_uris, (like_rows) =>
like_db = {}
for like_row in like_rows
like_db[like_row["post_uri"]] = like_row["likes"]

for row in rows
row["likes"] = like_db[row["post_uri"]]
@item_list.sync(rows)
Page.projector.scheduleRender()

@queryReposts post_uris, (repost_rows) =>
repost_db = {}
for repost_row in repost_rows
repost_db[repost_row["post_uri"]] = repost_row["reposts"]

for row in rows
row["reposts"] = repost_db[row["post_uri"]]
@item_list.sync(rows)
Page.projector.scheduleRender()

handleMoreClick: =>
@limit += 10
Expand Down
Loading