{{.DisplayTitle}}
@@ -39,9 +48,12 @@
{{if .Summary}}{{.SummaryHTML}}
{{end}}diff --git a/account.go b/account.go
index 2af9fce..d1e6a21 100644
--- a/account.go
+++ b/account.go
@@ -16,6 +16,7 @@ import (
"html/template"
"net/http"
"regexp"
+ "strconv"
"strings"
"sync"
"time"
@@ -691,6 +692,22 @@ func viewMyPostsAPI(app *App, u *User, w http.ResponseWriter, r *http.Request) e
return ErrBadRequestedType
}
+ isAnonPosts := r.FormValue("anonymous") == "1"
+ if isAnonPosts {
+ pageStr := r.FormValue("page")
+ pg, err := strconv.Atoi(pageStr)
+ if err != nil {
+ log.Error("Error parsing page parameter '%s': %s", pageStr, err)
+ pg = 1
+ }
+
+ p, err := app.db.GetAnonymousPosts(u, pg)
+ if err != nil {
+ return err
+ }
+ return impart.WriteSuccess(w, p, http.StatusOK)
+ }
+
var err error
p := GetPostsCache(u.ID)
if p == nil {
@@ -731,7 +748,7 @@ func viewMyCollectionsAPI(app *App, u *User, w http.ResponseWriter, r *http.Requ
}
func viewArticles(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
- p, err := app.db.GetAnonymousPosts(u)
+ p, err := app.db.GetAnonymousPosts(u, 1)
if err != nil {
log.Error("unable to fetch anon posts: %v", err)
}
diff --git a/database.go b/database.go
index 88b46e5..df300ce 100644
--- a/database.go
+++ b/database.go
@@ -77,7 +77,7 @@ type writestore interface {
GetTotalCollections() (int64, error)
GetTotalPosts() (int64, error)
GetTopPosts(u *User, alias string) (*[]PublicPost, error)
- GetAnonymousPosts(u *User) (*[]PublicPost, error)
+ GetAnonymousPosts(u *User, page int) (*[]PublicPost, error)
GetUserPosts(u *User) (*[]PublicPost, error)
CreateOwnedPost(post *SubmittedPost, accessToken, collAlias, hostName string) (*PublicPost, error)
@@ -1806,8 +1806,19 @@ func (db *datastore) GetTopPosts(u *User, alias string) (*[]PublicPost, error) {
return &posts, nil
}
-func (db *datastore) GetAnonymousPosts(u *User) (*[]PublicPost, error) {
- rows, err := db.Query("SELECT id, view_count, title, created, updated, content FROM posts WHERE owner_id = ? AND collection_id IS NULL ORDER BY created DESC", u.ID)
+func (db *datastore) GetAnonymousPosts(u *User, page int) (*[]PublicPost, error) {
+ pagePosts := 10
+ start := page*pagePosts - pagePosts
+ if page == 0 {
+ start = 0
+ pagePosts = 1000
+ }
+
+ limitStr := ""
+ if page > 0 {
+ limitStr = fmt.Sprintf(" LIMIT %d, %d", start, pagePosts)
+ }
+ rows, err := db.Query("SELECT id, view_count, title, created, updated, content FROM posts WHERE owner_id = ? AND collection_id IS NULL ORDER BY created DESC"+limitStr, u.ID)
if err != nil {
log.Error("Failed selecting from posts: %v", err)
return nil, impart.HTTPError{http.StatusInternalServerError, "Couldn't retrieve user anonymous posts."}
diff --git a/export.go b/export.go
index 592bc0c..bdfd7c4 100644
--- a/export.go
+++ b/export.go
@@ -110,7 +110,7 @@ func compileFullExport(app *App, u *User) *ExportUser {
log.Error("unable to fetch collections: %v", err)
}
- posts, err := app.db.GetAnonymousPosts(u)
+ posts, err := app.db.GetAnonymousPosts(u, 0)
if err != nil {
log.Error("unable to fetch anon posts: %v", err)
}
diff --git a/handle.go b/handle.go
index 01d5728..4c454ec 100644
--- a/handle.go
+++ b/handle.go
@@ -287,6 +287,26 @@ func (h *Handler) UserAPI(f userHandlerFunc) http.HandlerFunc {
return h.UserAll(false, f, apiAuth)
}
+// UserWebAPI handles endpoints that accept a user authorized either via the web (cookies) or an Authorization header.
+func (h *Handler) UserWebAPI(f userHandlerFunc) http.HandlerFunc {
+ return h.UserAll(false, f, func(app *App, r *http.Request) (*User, error) {
+ // Authorize user via cookies
+ u := getUserSession(app, r)
+ if u != nil {
+ return u, nil
+ }
+
+ // Fall back to access token, since user isn't logged in via web
+ var err error
+ u, err = apiAuth(app, r)
+ if err != nil {
+ return nil, err
+ }
+
+ return u, nil
+ })
+}
+
func (h *Handler) UserAll(web bool, f userHandlerFunc, a authFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
handleFunc := func() error {
diff --git a/routes.go b/routes.go
index 2b23bd1..1244e97 100644
--- a/routes.go
+++ b/routes.go
@@ -115,7 +115,7 @@ func InitRoutes(apper Apper, r *mux.Router) *mux.Router {
write.HandleFunc("/api/me", handler.All(viewMeAPI)).Methods("GET")
apiMe := write.PathPrefix("/api/me/").Subrouter()
apiMe.HandleFunc("/", handler.All(viewMeAPI)).Methods("GET")
- apiMe.HandleFunc("/posts", handler.UserAPI(viewMyPostsAPI)).Methods("GET")
+ apiMe.HandleFunc("/posts", handler.UserWebAPI(viewMyPostsAPI)).Methods("GET")
apiMe.HandleFunc("/collections", handler.UserAPI(viewMyCollectionsAPI)).Methods("GET")
apiMe.HandleFunc("/password", handler.All(updatePassphrase)).Methods("POST")
apiMe.HandleFunc("/self", handler.All(updateSettings)).Methods("POST")
diff --git a/static/js/posts.js b/static/js/posts.js
index 58b55a2..dfc30b7 100644
--- a/static/js/posts.js
+++ b/static/js/posts.js
@@ -181,9 +181,17 @@ var localPosts = function() {
undoDelete: UndoDelete,
};
}();
-var createPostEl = function(post) {
+var movePostHTML = function(postID) {
+ let $tmpl = document.getElementById('move-tmpl');
+ if ($tmpl === null) {
+ return "";
+ }
+ return $tmpl.innerHTML.replace(/POST_ID/g, postID);
+}
+var createPostEl = function(post, owned) {
var $post = document.createElement('div');
- var title = (post.title || post.id);
+ let p = H.createPost(post.id, "", post.body)
+ var title = (post.title || p.title || post.id);
title = title.replace(/
Sync error: ' + post.error + '
'; } if (post.summary) { + // TODO: switch to using p.summary, after ensuring it matches summary generated on the backend. $post.innerHTML += '' + post.summary.replace(/'; + } else if (post.body) { + var preview; + if (post.body.length > 140) { + preview = post.body.substr(0, 140) + '...'; + } else { + preview = post.body; + } + $post.innerHTML += '
' + preview.replace(/'; } return $post; }; diff --git a/templates/user/articles.tmpl b/templates/user/articles.tmpl index e96d51e..92f9c40 100644 --- a/templates/user/articles.tmpl +++ b/templates/user/articles.tmpl @@ -1,5 +1,14 @@ {{define "articles"}} {{template "header" .}} +
These are your draft posts. You can share them individually (without a blog) or move them to your blog when you're ready.
-Your anonymous and draft posts will show up here once you've published some. You'll be able to share them individually (without a blog) or move them to a blog when you're ready.
{{if not .SingleUser}}Alternatively, see your blogs and their posts on your Blogs page.
{{end}} +