Add Timeline
This commit is contained in:
parent
832848478d
commit
2f7ee34b98
@ -119,6 +119,8 @@ func (app *Application) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
app.Login(w, r)
|
app.Login(w, r)
|
||||||
case "change-session":
|
case "change-session":
|
||||||
app.ChangeSession(w, r)
|
app.ChangeSession(w, r)
|
||||||
|
case "timeline":
|
||||||
|
app.Timeline(w, r)
|
||||||
default:
|
default:
|
||||||
app.UserFeed(w, r)
|
app.UserFeed(w, r)
|
||||||
}
|
}
|
||||||
@ -308,6 +310,36 @@ func (app *Application) UserFeed(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (app *Application) Timeline(w http.ResponseWriter, r *http.Request) {
|
||||||
|
app.traceLog.Printf("'Timeline' handler (path: %q)", r.URL.Path)
|
||||||
|
|
||||||
|
c := persistence.NewTimelineCursor()
|
||||||
|
err := parse_cursor_value(&c, r)
|
||||||
|
if err != nil {
|
||||||
|
app.error_400_with_message(w, "invalid cursor (must be a number)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
feed, err := app.Profile.NextPage(c)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, persistence.ErrEndOfFeed) {
|
||||||
|
// TODO
|
||||||
|
} else {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data := UserProfileData{Feed: feed} // TODO: wrong struct
|
||||||
|
app.InfoLog.Printf(to_json(data))
|
||||||
|
|
||||||
|
if r.Header.Get("HX-Request") == "true" && c.CursorPosition == persistence.CURSOR_MIDDLE {
|
||||||
|
// It's a Show More request
|
||||||
|
app.buffered_render_tweet_htmx(w, "timeline", data)
|
||||||
|
} else {
|
||||||
|
app.buffered_render_tweet_page(w, "tpl/offline_timeline.tpl", data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type FormErrors map[string]string
|
type FormErrors map[string]string
|
||||||
|
|
||||||
type LoginForm struct {
|
type LoginForm struct {
|
||||||
|
@ -116,6 +116,50 @@ func TestUserFeedWithCursorBadNumber(t *testing.T) {
|
|||||||
require.Equal(resp.StatusCode, 400)
|
require.Equal(resp.StatusCode, 400)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Timeline page
|
||||||
|
// -------------
|
||||||
|
|
||||||
|
func TestTimeline(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
require := require.New(t)
|
||||||
|
|
||||||
|
resp := do_request(httptest.NewRequest("GET", "/timeline", nil))
|
||||||
|
require.Equal(resp.StatusCode, 200)
|
||||||
|
|
||||||
|
root, err := html.Parse(resp.Body)
|
||||||
|
require.NoError(err)
|
||||||
|
title_node := cascadia.Query(root, selector("title"))
|
||||||
|
assert.Equal(title_node.FirstChild.Data, "Offline Twitter | Timeline")
|
||||||
|
|
||||||
|
tweet_nodes := cascadia.QueryAll(root, selector(".tweet"))
|
||||||
|
assert.Len(tweet_nodes, 18)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimelineWithCursor(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
require := require.New(t)
|
||||||
|
|
||||||
|
resp := do_request(httptest.NewRequest("GET", "/timeline?cursor=1631935701", nil))
|
||||||
|
require.Equal(resp.StatusCode, 200)
|
||||||
|
|
||||||
|
root, err := html.Parse(resp.Body)
|
||||||
|
require.NoError(err)
|
||||||
|
title_node := cascadia.Query(root, selector("title"))
|
||||||
|
assert.Equal(title_node.FirstChild.Data, "Offline Twitter | Timeline")
|
||||||
|
|
||||||
|
tweet_nodes := cascadia.QueryAll(root, selector(".tweet"))
|
||||||
|
assert.Len(tweet_nodes, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimelineWithCursorBadNumber(t *testing.T) {
|
||||||
|
require := require.New(t)
|
||||||
|
|
||||||
|
// With a cursor but it sucks
|
||||||
|
resp := do_request(httptest.NewRequest("GET", "/timeline?cursor=asdf", nil))
|
||||||
|
require.Equal(resp.StatusCode, 400)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Tweet Detail page
|
// Tweet Detail page
|
||||||
// -----------------
|
// -----------------
|
||||||
|
|
||||||
|
@ -285,7 +285,7 @@ ul.quick-links {
|
|||||||
margin-bottom: 0.1em;
|
margin-bottom: 0.1em;
|
||||||
border-bottom: 1px solid var(--color-outline-gray);
|
border-bottom: 1px solid var(--color-outline-gray);
|
||||||
}
|
}
|
||||||
.user-feed-tweets .tweet {
|
.timeline .tweet {
|
||||||
border-bottom: 1px solid var(--color-twitter-off-white-dark);
|
border-bottom: 1px solid var(--color-twitter-off-white-dark);
|
||||||
padding-top: 0.8em;
|
padding-top: 0.8em;
|
||||||
padding-bottom: 0.8em;
|
padding-bottom: 0.8em;
|
||||||
@ -304,6 +304,7 @@ ul.quick-links {
|
|||||||
width: 40%;
|
width: 40%;
|
||||||
left: 30%;
|
left: 30%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.back-button {
|
.back-button {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="quick-links">
|
<ul class="quick-links">
|
||||||
<a class="unstyled-link" href="#">
|
<a class="unstyled-link" href="/timeline">
|
||||||
<li class="quick-link">
|
<li class="quick-link">
|
||||||
<img class="svg-icon" src="/static/icons/home.svg" />
|
<img class="svg-icon" src="/static/icons/home.svg" />
|
||||||
<span>Home</span>
|
<span>Home</span>
|
||||||
|
@ -43,9 +43,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="user-feed-tweets">
|
<div class="timeline user-feed-timeline">
|
||||||
{{range .Items}}
|
{{template "timeline" .}}
|
||||||
{{template "tweet" .}}
|
|
||||||
{{end}}
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user