mirror of
https://gitea.phreedom.club/localhost_frssoft/bloat.git
synced 2024-11-26 17:03:01 +00:00
Add frame based navigation
This commit is contained in:
parent
39a3bb7f35
commit
fe31d4197b
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
bloat
|
bloat
|
||||||
database
|
database
|
||||||
|
bloat.def.conf
|
||||||
|
3
BUGS
Normal file
3
BUGS
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Here's a list of known bugs in bloat:
|
||||||
|
|
||||||
|
- <frameset> and <frame> tags are not supported in HTML5
|
@ -1,21 +1,23 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
DefaultVisibility string `json:"default_visibility"`
|
DefaultVisibility string `json:"default_visibility"`
|
||||||
CopyScope bool `json:"copy_scope"`
|
CopyScope bool `json:"copy_scope"`
|
||||||
ThreadInNewTab bool `json:"thread_in_new_tab"`
|
ThreadInNewTab bool `json:"thread_in_new_tab"`
|
||||||
MaskNSFW bool `json:"mask_nfsw"`
|
MaskNSFW bool `json:"mask_nfsw"`
|
||||||
FluorideMode bool `json:"fluoride_mode"`
|
AutoRefreshNotifications bool `json:"auto_refresh_notifications"`
|
||||||
DarkMode bool `json:"dark_mode"`
|
FluorideMode bool `json:"fluoride_mode"`
|
||||||
|
DarkMode bool `json:"dark_mode"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSettings() *Settings {
|
func NewSettings() *Settings {
|
||||||
return &Settings{
|
return &Settings{
|
||||||
DefaultVisibility: "public",
|
DefaultVisibility: "public",
|
||||||
CopyScope: true,
|
CopyScope: true,
|
||||||
ThreadInNewTab: false,
|
ThreadInNewTab: false,
|
||||||
MaskNSFW: true,
|
MaskNSFW: true,
|
||||||
FluorideMode: false,
|
AutoRefreshNotifications: false,
|
||||||
DarkMode: false,
|
FluorideMode: false,
|
||||||
|
DarkMode: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,30 +14,17 @@ type Context struct {
|
|||||||
UserID string
|
UserID string
|
||||||
}
|
}
|
||||||
|
|
||||||
type HeaderData struct {
|
type NavData struct {
|
||||||
Title string
|
CommonData *CommonData
|
||||||
NotificationCount int
|
User *mastodon.Account
|
||||||
CustomCSS string
|
PostContext model.PostContext
|
||||||
CSRFToken string
|
|
||||||
}
|
|
||||||
|
|
||||||
type NavbarData struct {
|
|
||||||
User *mastodon.Account
|
|
||||||
NotificationCount int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommonData struct {
|
type CommonData struct {
|
||||||
HeaderData *HeaderData
|
Title string
|
||||||
NavbarData *NavbarData
|
CustomCSS string
|
||||||
}
|
CSRFToken string
|
||||||
|
AutoRefresh bool
|
||||||
func (c CommonData) IsCurrentUser(id string) bool {
|
|
||||||
if c.NavbarData != nil &&
|
|
||||||
c.NavbarData.User != nil &&
|
|
||||||
c.NavbarData.User.ID == id {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ErrorData struct {
|
type ErrorData struct {
|
||||||
@ -53,13 +40,16 @@ type SigninData struct {
|
|||||||
*CommonData
|
*CommonData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RootData struct {
|
||||||
|
Title string
|
||||||
|
}
|
||||||
|
|
||||||
type TimelineData struct {
|
type TimelineData struct {
|
||||||
*CommonData
|
*CommonData
|
||||||
Title string
|
Title string
|
||||||
Statuses []*mastodon.Status
|
Statuses []*mastodon.Status
|
||||||
NextLink string
|
NextLink string
|
||||||
PrevLink string
|
PrevLink string
|
||||||
PostContext model.PostContext
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ThreadData struct {
|
type ThreadData struct {
|
||||||
@ -72,8 +62,9 @@ type ThreadData struct {
|
|||||||
type NotificationData struct {
|
type NotificationData struct {
|
||||||
*CommonData
|
*CommonData
|
||||||
Notifications []*mastodon.Notification
|
Notifications []*mastodon.Notification
|
||||||
|
UnreadCount int
|
||||||
|
ReadID string
|
||||||
NextLink string
|
NextLink string
|
||||||
DarkMode bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserData struct {
|
type UserData struct {
|
||||||
@ -84,7 +75,6 @@ type UserData struct {
|
|||||||
Users []*mastodon.Account
|
Users []*mastodon.Account
|
||||||
Statuses []*mastodon.Status
|
Statuses []*mastodon.Status
|
||||||
NextLink string
|
NextLink string
|
||||||
DarkMode bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserSearchData struct {
|
type UserSearchData struct {
|
||||||
|
@ -19,6 +19,8 @@ type TemplateData struct {
|
|||||||
type Renderer interface {
|
type Renderer interface {
|
||||||
RenderSigninPage(ctx *Context, writer io.Writer, data *SigninData) (err error)
|
RenderSigninPage(ctx *Context, writer io.Writer, data *SigninData) (err error)
|
||||||
RenderErrorPage(ctx *Context, writer io.Writer, data *ErrorData)
|
RenderErrorPage(ctx *Context, writer io.Writer, data *ErrorData)
|
||||||
|
RenderRootPage(ctx *Context, writer io.Writer, data *RootData) (err error)
|
||||||
|
RenderNavPage(ctx *Context, writer io.Writer, data *NavData) (err error)
|
||||||
RenderTimelinePage(ctx *Context, writer io.Writer, data *TimelineData) (err error)
|
RenderTimelinePage(ctx *Context, writer io.Writer, data *TimelineData) (err error)
|
||||||
RenderThreadPage(ctx *Context, writer io.Writer, data *ThreadData) (err error)
|
RenderThreadPage(ctx *Context, writer io.Writer, data *ThreadData) (err error)
|
||||||
RenderNotificationPage(ctx *Context, writer io.Writer, data *NotificationData) (err error)
|
RenderNotificationPage(ctx *Context, writer io.Writer, data *NotificationData) (err error)
|
||||||
@ -67,6 +69,16 @@ func (r *renderer) RenderErrorPage(ctx *Context, writer io.Writer,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *renderer) RenderNavPage(ctx *Context, writer io.Writer,
|
||||||
|
data *NavData) (err error) {
|
||||||
|
return r.template.ExecuteTemplate(writer, "nav.tmpl", WithContext(data, ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *renderer) RenderRootPage(ctx *Context, writer io.Writer,
|
||||||
|
data *RootData) (err error) {
|
||||||
|
return r.template.ExecuteTemplate(writer, "root.tmpl", WithContext(data, ctx))
|
||||||
|
}
|
||||||
|
|
||||||
func (r *renderer) RenderTimelinePage(ctx *Context, writer io.Writer,
|
func (r *renderer) RenderTimelinePage(ctx *Context, writer io.Writer,
|
||||||
data *TimelineData) (err error) {
|
data *TimelineData) (err error) {
|
||||||
return r.template.ExecuteTemplate(writer, "timeline.tmpl", WithContext(data, ctx))
|
return r.template.ExecuteTemplate(writer, "timeline.tmpl", WithContext(data, ctx))
|
||||||
|
@ -68,6 +68,22 @@ func (s *as) ServeSigninPage(ctx context.Context, c *model.Client) (err error) {
|
|||||||
return s.Service.ServeSigninPage(ctx, c)
|
return s.Service.ServeSigninPage(ctx, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *as) ServeRootPage(ctx context.Context, c *model.Client) (err error) {
|
||||||
|
err = s.authenticateClient(ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return s.Service.ServeRootPage(ctx, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *as) ServeNavPage(ctx context.Context, c *model.Client) (err error) {
|
||||||
|
err = s.authenticateClient(ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return s.Service.ServeNavPage(ctx, c)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *as) ServeTimelinePage(ctx context.Context, c *model.Client, tType string,
|
func (s *as) ServeTimelinePage(ctx context.Context, c *model.Client, tType string,
|
||||||
maxID string, minID string) (err error) {
|
maxID string, minID string) (err error) {
|
||||||
err = s.authenticateClient(ctx, c)
|
err = s.authenticateClient(ctx, c)
|
||||||
@ -382,3 +398,16 @@ func (s *as) Delete(ctx context.Context, c *model.Client, id string) (err error)
|
|||||||
}
|
}
|
||||||
return s.Service.Delete(ctx, c, id)
|
return s.Service.Delete(ctx, c, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *as) ReadNotifications(ctx context.Context, c *model.Client,
|
||||||
|
maxID string) (err error) {
|
||||||
|
err = s.authenticateClient(ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = checkCSRF(ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return s.Service.ReadNotifications(ctx, c, maxID)
|
||||||
|
}
|
||||||
|
@ -34,6 +34,22 @@ func (s *ls) ServeSigninPage(ctx context.Context, c *model.Client) (err error) {
|
|||||||
return s.Service.ServeSigninPage(ctx, c)
|
return s.Service.ServeSigninPage(ctx, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ls) ServeRootPage(ctx context.Context, c *model.Client) (err error) {
|
||||||
|
defer func(begin time.Time) {
|
||||||
|
s.logger.Printf("method=%v, took=%v, err=%v\n",
|
||||||
|
"ServeRootPage", time.Since(begin), err)
|
||||||
|
}(time.Now())
|
||||||
|
return s.Service.ServeRootPage(ctx, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ls) ServeNavPage(ctx context.Context, c *model.Client) (err error) {
|
||||||
|
defer func(begin time.Time) {
|
||||||
|
s.logger.Printf("method=%v, took=%v, err=%v\n",
|
||||||
|
"ServeNavPage", time.Since(begin), err)
|
||||||
|
}(time.Now())
|
||||||
|
return s.Service.ServeNavPage(ctx, c)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *ls) ServeTimelinePage(ctx context.Context, c *model.Client, tType string,
|
func (s *ls) ServeTimelinePage(ctx context.Context, c *model.Client, tType string,
|
||||||
maxID string, minID string) (err error) {
|
maxID string, minID string) (err error) {
|
||||||
defer func(begin time.Time) {
|
defer func(begin time.Time) {
|
||||||
@ -276,3 +292,12 @@ func (s *ls) Delete(ctx context.Context, c *model.Client, id string) (err error)
|
|||||||
}(time.Now())
|
}(time.Now())
|
||||||
return s.Service.Delete(ctx, c, id)
|
return s.Service.Delete(ctx, c, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ls) ReadNotifications(ctx context.Context, c *model.Client,
|
||||||
|
maxID string) (err error) {
|
||||||
|
defer func(begin time.Time) {
|
||||||
|
s.logger.Printf("method=%v, max_id=%v, took=%v, err=%v\n",
|
||||||
|
"ReadNotifications", maxID, time.Since(begin), err)
|
||||||
|
}(time.Now())
|
||||||
|
return s.Service.ReadNotifications(ctx, c, maxID)
|
||||||
|
}
|
||||||
|
@ -21,6 +21,8 @@ var (
|
|||||||
type Service interface {
|
type Service interface {
|
||||||
ServeErrorPage(ctx context.Context, c *model.Client, err error)
|
ServeErrorPage(ctx context.Context, c *model.Client, err error)
|
||||||
ServeSigninPage(ctx context.Context, c *model.Client) (err error)
|
ServeSigninPage(ctx context.Context, c *model.Client) (err error)
|
||||||
|
ServeRootPage(ctx context.Context, c *model.Client) (err error)
|
||||||
|
ServeNavPage(ctx context.Context, c *model.Client) (err error)
|
||||||
ServeTimelinePage(ctx context.Context, c *model.Client, tType string, maxID string, minID string) (err error)
|
ServeTimelinePage(ctx context.Context, c *model.Client, tType string, maxID string, minID string) (err error)
|
||||||
ServeThreadPage(ctx context.Context, c *model.Client, id string, reply bool) (err error)
|
ServeThreadPage(ctx context.Context, c *model.Client, id string, reply bool) (err error)
|
||||||
ServeLikedByPage(ctx context.Context, c *model.Client, id string) (err error)
|
ServeLikedByPage(ctx context.Context, c *model.Client, id string) (err error)
|
||||||
@ -53,6 +55,7 @@ type Service interface {
|
|||||||
MuteConversation(ctx context.Context, c *model.Client, id string) (err error)
|
MuteConversation(ctx context.Context, c *model.Client, id string) (err error)
|
||||||
UnMuteConversation(ctx context.Context, c *model.Client, id string) (err error)
|
UnMuteConversation(ctx context.Context, c *model.Client, id string) (err error)
|
||||||
Delete(ctx context.Context, c *model.Client, id string) (err error)
|
Delete(ctx context.Context, c *model.Client, id string) (err error)
|
||||||
|
ReadNotifications(ctx context.Context, c *model.Client, maxID string) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type service struct {
|
type service struct {
|
||||||
@ -126,45 +129,14 @@ func addToReplyMap(m map[string][]mastodon.ReplyInfo, key interface{},
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (svc *service) getCommonData(ctx context.Context, c *model.Client,
|
func (svc *service) getCommonData(ctx context.Context, c *model.Client,
|
||||||
title string) (data *renderer.CommonData, err error) {
|
title string) (data *renderer.CommonData) {
|
||||||
|
data = &renderer.CommonData{
|
||||||
data = new(renderer.CommonData)
|
Title: title + " - " + svc.clientName,
|
||||||
data.HeaderData = &renderer.HeaderData{
|
CustomCSS: svc.customCSS,
|
||||||
Title: title + " - " + svc.clientName,
|
|
||||||
NotificationCount: 0,
|
|
||||||
CustomCSS: svc.customCSS,
|
|
||||||
}
|
}
|
||||||
|
if c != nil && c.Session.IsLoggedIn() {
|
||||||
if c == nil || !c.Session.IsLoggedIn() {
|
data.CSRFToken = c.Session.CSRFToken
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifications, err := c.GetNotifications(ctx, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var notificationCount int
|
|
||||||
for i := range notifications {
|
|
||||||
if notifications[i].Pleroma != nil &&
|
|
||||||
!notifications[i].Pleroma.IsSeen {
|
|
||||||
notificationCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u, err := c.GetAccountCurrentUser(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
data.NavbarData = &renderer.NavbarData{
|
|
||||||
User: u,
|
|
||||||
NotificationCount: notificationCount,
|
|
||||||
}
|
|
||||||
|
|
||||||
data.HeaderData.NotificationCount = notificationCount
|
|
||||||
data.HeaderData.CSRFToken = c.Session.CSRFToken
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,11 +146,7 @@ func (svc *service) ServeErrorPage(ctx context.Context, c *model.Client, err err
|
|||||||
errStr = err.Error()
|
errStr = err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
commonData, err := svc.getCommonData(ctx, nil, "error")
|
commonData := svc.getCommonData(ctx, nil, "error")
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.ErrorData{
|
data := &renderer.ErrorData{
|
||||||
CommonData: commonData,
|
CommonData: commonData,
|
||||||
Error: errStr,
|
Error: errStr,
|
||||||
@ -191,11 +159,7 @@ func (svc *service) ServeErrorPage(ctx context.Context, c *model.Client, err err
|
|||||||
func (svc *service) ServeSigninPage(ctx context.Context, c *model.Client) (
|
func (svc *service) ServeSigninPage(ctx context.Context, c *model.Client) (
|
||||||
err error) {
|
err error) {
|
||||||
|
|
||||||
commonData, err := svc.getCommonData(ctx, nil, "signin")
|
commonData := svc.getCommonData(ctx, nil, "signin")
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.SigninData{
|
data := &renderer.SigninData{
|
||||||
CommonData: commonData,
|
CommonData: commonData,
|
||||||
}
|
}
|
||||||
@ -204,6 +168,37 @@ func (svc *service) ServeSigninPage(ctx context.Context, c *model.Client) (
|
|||||||
return svc.renderer.RenderSigninPage(rCtx, c.Writer, data)
|
return svc.renderer.RenderSigninPage(rCtx, c.Writer, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (svc *service) ServeRootPage(ctx context.Context, c *model.Client) (err error) {
|
||||||
|
data := &renderer.RootData{
|
||||||
|
Title: svc.clientName,
|
||||||
|
}
|
||||||
|
|
||||||
|
rCtx := getRendererContext(c)
|
||||||
|
return svc.renderer.RenderRootPage(rCtx, c.Writer, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svc *service) ServeNavPage(ctx context.Context, c *model.Client) (err error) {
|
||||||
|
u, err := c.GetAccountCurrentUser(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
postContext := model.PostContext{
|
||||||
|
DefaultVisibility: c.Session.Settings.DefaultVisibility,
|
||||||
|
Formats: svc.postFormats,
|
||||||
|
}
|
||||||
|
|
||||||
|
commonData := svc.getCommonData(ctx, c, "Nav")
|
||||||
|
data := &renderer.NavData{
|
||||||
|
User: u,
|
||||||
|
CommonData: commonData,
|
||||||
|
PostContext: postContext,
|
||||||
|
}
|
||||||
|
|
||||||
|
rCtx := getRendererContext(c)
|
||||||
|
return svc.renderer.RenderNavPage(rCtx, c.Writer, data)
|
||||||
|
}
|
||||||
|
|
||||||
func (svc *service) ServeTimelinePage(ctx context.Context, c *model.Client,
|
func (svc *service) ServeTimelinePage(ctx context.Context, c *model.Client,
|
||||||
tType string, maxID string, minID string) (err error) {
|
tType string, maxID string, minID string) (err error) {
|
||||||
|
|
||||||
@ -269,23 +264,13 @@ func (svc *service) ServeTimelinePage(ctx context.Context, c *model.Client,
|
|||||||
nextLink = fmt.Sprintf("/timeline/%s?max_id=%s", tType, pg.MaxID)
|
nextLink = fmt.Sprintf("/timeline/%s?max_id=%s", tType, pg.MaxID)
|
||||||
}
|
}
|
||||||
|
|
||||||
postContext := model.PostContext{
|
commonData := svc.getCommonData(ctx, c, tType+" timeline ")
|
||||||
DefaultVisibility: c.Session.Settings.DefaultVisibility,
|
|
||||||
Formats: svc.postFormats,
|
|
||||||
}
|
|
||||||
|
|
||||||
commonData, err := svc.getCommonData(ctx, c, tType+" timeline ")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.TimelineData{
|
data := &renderer.TimelineData{
|
||||||
Title: title,
|
Title: title,
|
||||||
Statuses: statuses,
|
Statuses: statuses,
|
||||||
NextLink: nextLink,
|
NextLink: nextLink,
|
||||||
PrevLink: prevLink,
|
PrevLink: prevLink,
|
||||||
PostContext: postContext,
|
CommonData: commonData,
|
||||||
CommonData: commonData,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rCtx := getRendererContext(c)
|
rCtx := getRendererContext(c)
|
||||||
@ -356,11 +341,7 @@ func (svc *service) ServeThreadPage(ctx context.Context, c *model.Client,
|
|||||||
addToReplyMap(replies, statuses[i].InReplyToID, statuses[i].ID, i+1)
|
addToReplyMap(replies, statuses[i].InReplyToID, statuses[i].ID, i+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
commonData, err := svc.getCommonData(ctx, c, "post by "+status.Account.DisplayName)
|
commonData := svc.getCommonData(ctx, c, "post by "+status.Account.DisplayName)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.ThreadData{
|
data := &renderer.ThreadData{
|
||||||
Statuses: statuses,
|
Statuses: statuses,
|
||||||
PostContext: postContext,
|
PostContext: postContext,
|
||||||
@ -380,11 +361,7 @@ func (svc *service) ServeLikedByPage(ctx context.Context, c *model.Client,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
commonData, err := svc.getCommonData(ctx, c, "likes")
|
commonData := svc.getCommonData(ctx, c, "likes")
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.LikedByData{
|
data := &renderer.LikedByData{
|
||||||
CommonData: commonData,
|
CommonData: commonData,
|
||||||
Users: likers,
|
Users: likers,
|
||||||
@ -402,11 +379,7 @@ func (svc *service) ServeRetweetedByPage(ctx context.Context, c *model.Client,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
commonData, err := svc.getCommonData(ctx, c, "retweets")
|
commonData := svc.getCommonData(ctx, c, "retweets")
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.RetweetedByData{
|
data := &renderer.RetweetedByData{
|
||||||
CommonData: commonData,
|
CommonData: commonData,
|
||||||
Users: retweeters,
|
Users: retweeters,
|
||||||
@ -421,6 +394,7 @@ func (svc *service) ServeNotificationPage(ctx context.Context, c *model.Client,
|
|||||||
|
|
||||||
var nextLink string
|
var nextLink string
|
||||||
var unreadCount int
|
var unreadCount int
|
||||||
|
var readID string
|
||||||
var pg = mastodon.Pagination{
|
var pg = mastodon.Pagination{
|
||||||
MaxID: maxID,
|
MaxID: maxID,
|
||||||
MinID: minID,
|
MinID: minID,
|
||||||
@ -439,23 +413,19 @@ func (svc *service) ServeNotificationPage(ctx context.Context, c *model.Client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if unreadCount > 0 {
|
if unreadCount > 0 {
|
||||||
err := c.ReadNotifications(ctx, notifications[0].ID)
|
readID = notifications[0].ID
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(pg.MaxID) > 0 {
|
if len(notifications) == 20 && len(pg.MaxID) > 0 {
|
||||||
nextLink = "/notifications?max_id=" + pg.MaxID
|
nextLink = "/notifications?max_id=" + pg.MaxID
|
||||||
}
|
}
|
||||||
|
|
||||||
commonData, err := svc.getCommonData(ctx, c, "notifications")
|
commonData := svc.getCommonData(ctx, c, "notifications")
|
||||||
if err != nil {
|
commonData.AutoRefresh = c.Session.Settings.AutoRefreshNotifications
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.NotificationData{
|
data := &renderer.NotificationData{
|
||||||
Notifications: notifications,
|
Notifications: notifications,
|
||||||
|
UnreadCount: unreadCount,
|
||||||
|
ReadID: readID,
|
||||||
NextLink: nextLink,
|
NextLink: nextLink,
|
||||||
CommonData: commonData,
|
CommonData: commonData,
|
||||||
}
|
}
|
||||||
@ -521,14 +491,10 @@ func (svc *service) ServeUserPage(ctx context.Context, c *model.Client,
|
|||||||
return errInvalidArgument
|
return errInvalidArgument
|
||||||
}
|
}
|
||||||
|
|
||||||
commonData, err := svc.getCommonData(ctx, c, user.DisplayName)
|
commonData := svc.getCommonData(ctx, c, user.DisplayName)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.UserData{
|
data := &renderer.UserData{
|
||||||
User: user,
|
User: user,
|
||||||
IsCurrent: commonData.IsCurrentUser(user.ID),
|
IsCurrent: c.Session.UserID == user.ID,
|
||||||
Type: pageType,
|
Type: pageType,
|
||||||
Users: users,
|
Users: users,
|
||||||
Statuses: statuses,
|
Statuses: statuses,
|
||||||
@ -564,11 +530,7 @@ func (svc *service) ServeUserSearchPage(ctx context.Context, c *model.Client,
|
|||||||
title += " \"" + q + "\""
|
title += " \"" + q + "\""
|
||||||
}
|
}
|
||||||
|
|
||||||
commonData, err := svc.getCommonData(ctx, c, title)
|
commonData := svc.getCommonData(ctx, c, title)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.UserSearchData{
|
data := &renderer.UserSearchData{
|
||||||
CommonData: commonData,
|
CommonData: commonData,
|
||||||
User: user,
|
User: user,
|
||||||
@ -582,11 +544,7 @@ func (svc *service) ServeUserSearchPage(ctx context.Context, c *model.Client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (svc *service) ServeAboutPage(ctx context.Context, c *model.Client) (err error) {
|
func (svc *service) ServeAboutPage(ctx context.Context, c *model.Client) (err error) {
|
||||||
commonData, err := svc.getCommonData(ctx, c, "about")
|
commonData := svc.getCommonData(ctx, c, "about")
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.AboutData{
|
data := &renderer.AboutData{
|
||||||
CommonData: commonData,
|
CommonData: commonData,
|
||||||
}
|
}
|
||||||
@ -596,16 +554,12 @@ func (svc *service) ServeAboutPage(ctx context.Context, c *model.Client) (err er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (svc *service) ServeEmojiPage(ctx context.Context, c *model.Client) (err error) {
|
func (svc *service) ServeEmojiPage(ctx context.Context, c *model.Client) (err error) {
|
||||||
commonData, err := svc.getCommonData(ctx, c, "emojis")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
emojis, err := c.GetInstanceEmojis(ctx)
|
emojis, err := c.GetInstanceEmojis(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commonData := svc.getCommonData(ctx, c, "emojis")
|
||||||
data := &renderer.EmojiData{
|
data := &renderer.EmojiData{
|
||||||
Emojis: emojis,
|
Emojis: emojis,
|
||||||
CommonData: commonData,
|
CommonData: commonData,
|
||||||
@ -636,11 +590,7 @@ func (svc *service) ServeSearchPage(ctx context.Context, c *model.Client,
|
|||||||
title += " \"" + q + "\""
|
title += " \"" + q + "\""
|
||||||
}
|
}
|
||||||
|
|
||||||
commonData, err := svc.getCommonData(ctx, c, title)
|
commonData := svc.getCommonData(ctx, c, title)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.SearchData{
|
data := &renderer.SearchData{
|
||||||
CommonData: commonData,
|
CommonData: commonData,
|
||||||
Q: q,
|
Q: q,
|
||||||
@ -655,11 +605,7 @@ func (svc *service) ServeSearchPage(ctx context.Context, c *model.Client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (svc *service) ServeSettingsPage(ctx context.Context, c *model.Client) (err error) {
|
func (svc *service) ServeSettingsPage(ctx context.Context, c *model.Client) (err error) {
|
||||||
commonData, err := svc.getCommonData(ctx, c, "settings")
|
commonData := svc.getCommonData(ctx, c, "settings")
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := &renderer.SettingsData{
|
data := &renderer.SettingsData{
|
||||||
CommonData: commonData,
|
CommonData: commonData,
|
||||||
Settings: &c.Session.Settings,
|
Settings: &c.Session.Settings,
|
||||||
@ -911,3 +857,8 @@ func (svc *service) Delete(ctx context.Context, c *model.Client,
|
|||||||
id string) (err error) {
|
id string) (err error) {
|
||||||
return c.DeleteStatus(ctx, id)
|
return c.DeleteStatus(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (svc *service) ReadNotifications(ctx context.Context, c *model.Client,
|
||||||
|
maxID string) (err error) {
|
||||||
|
return c.ReadNotifications(ctx, maxID)
|
||||||
|
}
|
||||||
|
@ -64,14 +64,30 @@ func NewHandler(s Service, staticDir string) http.Handler {
|
|||||||
|
|
||||||
rootPage := func(w http.ResponseWriter, req *http.Request) {
|
rootPage := func(w http.ResponseWriter, req *http.Request) {
|
||||||
sessionID, _ := req.Cookie("session_id")
|
sessionID, _ := req.Cookie("session_id")
|
||||||
|
|
||||||
location := "/signin"
|
|
||||||
if sessionID != nil && len(sessionID.Value) > 0 {
|
if sessionID != nil && len(sessionID.Value) > 0 {
|
||||||
location = "/timeline/home"
|
c := newClient(w)
|
||||||
|
ctx := newCtxWithSesion(req)
|
||||||
|
err := s.ServeRootPage(ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
s.ServeErrorPage(ctx, c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
w.Header().Add("Location", "/signin")
|
||||||
|
w.WriteHeader(http.StatusFound)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Add("Location", location)
|
navPage := func(w http.ResponseWriter, req *http.Request) {
|
||||||
w.WriteHeader(http.StatusFound)
|
c := newClient(w)
|
||||||
|
ctx := newCtxWithSesion(req)
|
||||||
|
err := s.ServeNavPage(ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
s.ServeErrorPage(ctx, c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signinPage := func(w http.ResponseWriter, req *http.Request) {
|
signinPage := func(w http.ResponseWriter, req *http.Request) {
|
||||||
@ -297,7 +313,7 @@ func NewHandler(s Service, staticDir string) http.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Add("Location", "/timeline/home")
|
w.Header().Add("Location", "/")
|
||||||
w.WriteHeader(http.StatusFound)
|
w.WriteHeader(http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +342,7 @@ func NewHandler(s Service, staticDir string) http.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
location := "/timeline/home" + "#status-" + id
|
location := req.Header.Get("Referer")
|
||||||
if len(replyToID) > 0 {
|
if len(replyToID) > 0 {
|
||||||
location = "/thread/" + replyToID + "#status-" + id
|
location = "/thread/" + replyToID + "#status-" + id
|
||||||
}
|
}
|
||||||
@ -540,16 +556,18 @@ func NewHandler(s Service, staticDir string) http.Handler {
|
|||||||
copyScope := req.FormValue("copy_scope") == "true"
|
copyScope := req.FormValue("copy_scope") == "true"
|
||||||
threadInNewTab := req.FormValue("thread_in_new_tab") == "true"
|
threadInNewTab := req.FormValue("thread_in_new_tab") == "true"
|
||||||
maskNSFW := req.FormValue("mask_nsfw") == "true"
|
maskNSFW := req.FormValue("mask_nsfw") == "true"
|
||||||
|
arn := req.FormValue("auto_refresh_notifications") == "true"
|
||||||
fluorideMode := req.FormValue("fluoride_mode") == "true"
|
fluorideMode := req.FormValue("fluoride_mode") == "true"
|
||||||
darkMode := req.FormValue("dark_mode") == "true"
|
darkMode := req.FormValue("dark_mode") == "true"
|
||||||
|
|
||||||
settings := &model.Settings{
|
settings := &model.Settings{
|
||||||
DefaultVisibility: visibility,
|
DefaultVisibility: visibility,
|
||||||
CopyScope: copyScope,
|
CopyScope: copyScope,
|
||||||
ThreadInNewTab: threadInNewTab,
|
ThreadInNewTab: threadInNewTab,
|
||||||
MaskNSFW: maskNSFW,
|
MaskNSFW: maskNSFW,
|
||||||
FluorideMode: fluorideMode,
|
AutoRefreshNotifications: arn,
|
||||||
DarkMode: darkMode,
|
FluorideMode: fluorideMode,
|
||||||
|
DarkMode: darkMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.SaveSettings(ctx, c, settings)
|
err := s.SaveSettings(ctx, c, settings)
|
||||||
@ -559,7 +577,7 @@ func NewHandler(s Service, staticDir string) http.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Add("Location", req.Header.Get("Referer"))
|
w.Header().Add("Location", "/")
|
||||||
w.WriteHeader(http.StatusFound)
|
w.WriteHeader(http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,6 +629,22 @@ func NewHandler(s Service, staticDir string) http.Handler {
|
|||||||
w.WriteHeader(http.StatusFound)
|
w.WriteHeader(http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readNotifications := func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
c := newClient(w)
|
||||||
|
ctx := newCtxWithSesionCSRF(req, req.FormValue("csrf_token"))
|
||||||
|
maxID := req.URL.Query().Get("max_id")
|
||||||
|
|
||||||
|
err := s.ReadNotifications(ctx, c, maxID)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
s.ServeErrorPage(ctx, c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Add("Location", req.Header.Get("Referer"))
|
||||||
|
w.WriteHeader(http.StatusFound)
|
||||||
|
}
|
||||||
|
|
||||||
signout := func(w http.ResponseWriter, req *http.Request) {
|
signout := func(w http.ResponseWriter, req *http.Request) {
|
||||||
// TODO remove session from database
|
// TODO remove session from database
|
||||||
http.SetCookie(w, &http.Cookie{
|
http.SetCookie(w, &http.Cookie{
|
||||||
@ -694,7 +728,9 @@ func NewHandler(s Service, staticDir string) http.Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
r.HandleFunc("/", rootPage).Methods(http.MethodGet)
|
r.HandleFunc("/", rootPage).Methods(http.MethodGet)
|
||||||
|
r.HandleFunc("/nav", navPage).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/signin", signinPage).Methods(http.MethodGet)
|
r.HandleFunc("/signin", signinPage).Methods(http.MethodGet)
|
||||||
|
r.HandleFunc("//{type}", timelinePage).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/timeline/{type}", timelinePage).Methods(http.MethodGet)
|
r.HandleFunc("/timeline/{type}", timelinePage).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/timeline", timelineOldPage).Methods(http.MethodGet)
|
r.HandleFunc("/timeline", timelineOldPage).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/thread/{id}", threadPage).Methods(http.MethodGet)
|
r.HandleFunc("/thread/{id}", threadPage).Methods(http.MethodGet)
|
||||||
@ -726,6 +762,7 @@ func NewHandler(s Service, staticDir string) http.Handler {
|
|||||||
r.HandleFunc("/muteconv/{id}", muteConversation).Methods(http.MethodPost)
|
r.HandleFunc("/muteconv/{id}", muteConversation).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/unmuteconv/{id}", unMuteConversation).Methods(http.MethodPost)
|
r.HandleFunc("/unmuteconv/{id}", unMuteConversation).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/delete/{id}", delete).Methods(http.MethodPost)
|
r.HandleFunc("/delete/{id}", delete).Methods(http.MethodPost)
|
||||||
|
r.HandleFunc("/notifications/read", readNotifications).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/signout", signout).Methods(http.MethodGet)
|
r.HandleFunc("/signout", signout).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/fluoride/like/{id}", fLike).Methods(http.MethodPost)
|
r.HandleFunc("/fluoride/like/{id}", fLike).Methods(http.MethodPost)
|
||||||
r.HandleFunc("/fluoride/unlike/{id}", fUnlike).Methods(http.MethodPost)
|
r.HandleFunc("/fluoride/unlike/{id}", fUnlike).Methods(http.MethodPost)
|
||||||
|
@ -460,6 +460,19 @@ a:hover,
|
|||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification-title-container>* {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-title {
|
||||||
|
font-size: 18pt;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-refresh {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
background-color: #222222;
|
background-color: #222222;
|
||||||
background-image: none;
|
background-image: none;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}}
|
|
||||||
<div class="page-title"> About </div>
|
<div class="page-title"> About </div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}}
|
|
||||||
<div class="page-title"> Emojis </div>
|
<div class="page-title"> Emojis </div>
|
||||||
|
|
||||||
<div class="emoji-list-container">
|
<div class="emoji-list-container">
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
<div class="page-title"> Error </div>
|
<div class="page-title"> Error </div>
|
||||||
|
|
||||||
<div class="error-text"> {{.Error}} </div>
|
<div class="error-text"> {{.Error}} </div>
|
||||||
<div>
|
<div>
|
||||||
<a href="/timeline/home">Home</a>
|
<a href="/timeline/home">Home</a>
|
||||||
<a href="/signin">Sign In</a>
|
<a href="/signin" target="_top">Sign In</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{template "footer.tmpl"}}
|
{{template "footer.tmpl"}}
|
||||||
|
@ -7,7 +7,10 @@
|
|||||||
{{if .CSRFToken}}
|
{{if .CSRFToken}}
|
||||||
<meta name="csrf_token" content="{{.CSRFToken}}">
|
<meta name="csrf_token" content="{{.CSRFToken}}">
|
||||||
{{end}}
|
{{end}}
|
||||||
<title>{{if gt .NotificationCount 0}}({{.NotificationCount}}) {{end}}{{.Title}}</title>
|
{{if .AutoRefresh}}
|
||||||
|
<meta http-equiv="refresh" content="30">
|
||||||
|
{{end}}
|
||||||
|
<title>{{.Title}}</title>
|
||||||
<link rel="stylesheet" href="/static/style.css">
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
{{if .CustomCSS}}
|
{{if .CustomCSS}}
|
||||||
<link rel="stylesheet" href="{{.CustomCSS}}">
|
<link rel="stylesheet" href="{{.CustomCSS}}">
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}}
|
|
||||||
<div class="page-title"> Liked By </div>
|
<div class="page-title"> Liked By </div>
|
||||||
|
|
||||||
{{template "userlist.tmpl" (WithContext .Users $.Ctx)}}
|
{{template "userlist.tmpl" (WithContext .Users $.Ctx)}}
|
||||||
|
34
templates/nav.tmpl
Normal file
34
templates/nav.tmpl
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{{with .Data}}
|
||||||
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
|
<div class="user-info">
|
||||||
|
<div class="user-info-img-container">
|
||||||
|
<a class="img-link" href="/timeline/home" title="home" target="main">
|
||||||
|
<img class="user-info-img" src="{{.User.AvatarStatic}}" alt="profile-avatar" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="user-info-details-container">
|
||||||
|
<div>
|
||||||
|
<span class="status-dname"> {{EmojiFilter .User.DisplayName .User.Emojis}} </span>
|
||||||
|
<a class="nav-link" href="/user/{{.User.ID}}" target="main">
|
||||||
|
<span class="status-uname"> {{.User.Acct}} </span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a class="nav-link" href="/timeline/home" target="main">home</a>
|
||||||
|
<a class="nav-link" href="/timeline/direct" target="main">direct</a>
|
||||||
|
<a class="nav-link" href="/timeline/local" target="main">local</a>
|
||||||
|
<a class="nav-link" href="/timeline/twkn" target="main">twkn</a>
|
||||||
|
<a class="nav-link" href="/search" target="main">search</a>
|
||||||
|
<a class="nav-link" href="/about" target="main">about</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a class="nav-link" href="/settings" target="_top">settings</a>
|
||||||
|
<a class="nav-link" href="/signout" target="_top">sign out</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{template "postform.tmpl" (WithContext .PostContext $.Ctx)}}
|
||||||
|
|
||||||
|
{{template "footer.tmpl"}}
|
||||||
|
{{end}}
|
@ -1,30 +0,0 @@
|
|||||||
{{with .Data}}
|
|
||||||
<div class="user-info">
|
|
||||||
<div class="user-info-img-container">
|
|
||||||
<a class="img-link" href="/timeline/home" title="home">
|
|
||||||
<img class="user-info-img" src="{{.User.AvatarStatic}}" alt="profile-avatar" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="user-info-details-container">
|
|
||||||
<div>
|
|
||||||
<span class="status-dname"> {{EmojiFilter .User.DisplayName .User.Emojis}} </span>
|
|
||||||
<a class="nav-link" href="/user/{{.User.ID}}">
|
|
||||||
<span class="status-uname"> {{.User.Acct}} </span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a class="nav-link" href="/timeline/home">home</a>
|
|
||||||
<a class="nav-link" href="/notifications">notifications{{if gt .NotificationCount 0}}({{.NotificationCount}}){{end}}</a>
|
|
||||||
<a class="nav-link" href="/timeline/direct">direct</a>
|
|
||||||
<a class="nav-link" href="/timeline/local">local</a>
|
|
||||||
<a class="nav-link" href="/timeline/twkn">twkn</a>
|
|
||||||
<a class="nav-link" href="/search">search</a>
|
|
||||||
<a class="nav-link" href="/about">about</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a class="nav-link" href="/settings">settings</a>
|
|
||||||
<a class="nav-link" href="/signout">sign out</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
@ -1,14 +1,25 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}}
|
<div class="notification-title-container">
|
||||||
<div class="page-title"> Notifications </div>
|
<div class="notification-title">
|
||||||
|
Notifications
|
||||||
|
{{if gt .UnreadCount 0}}({{.UnreadCount }}){{end}}
|
||||||
|
</div>
|
||||||
|
<a class="notification-refresh" href="/notifications">refresh</a>
|
||||||
|
{{if .ReadID}}
|
||||||
|
<form action="/notifications/read?max_id={{.ReadID}}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
||||||
|
<input type="submit" value="read" class="btn-link">
|
||||||
|
</form>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{range .Notifications}}
|
{{range .Notifications}}
|
||||||
<div class="notification-container {{if .Pleroma}}{{if not .Pleroma.IsSeen}}unread{{end}}{{end}}">
|
<div class="notification-container {{if .Pleroma}}{{if not .Pleroma.IsSeen}}unread{{end}}{{end}}">
|
||||||
{{if eq .Type "follow"}}
|
{{if eq .Type "follow"}}
|
||||||
<div class="notification-follow-container">
|
<div class="notification-follow-container">
|
||||||
<div class="status-profile-img-container">
|
<div class="status-profile-img-container">
|
||||||
<a class="img-link" href="/user/{{.Account.ID}}" >
|
<a class="img-link" href="/user/{{.Account.ID}}" target="main" >
|
||||||
<img class="status-profile-img" src="{{.Account.AvatarStatic}}" alt="profile-avatar" />
|
<img class="status-profile-img" src="{{.Account.AvatarStatic}}" alt="profile-avatar" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -31,7 +42,7 @@
|
|||||||
|
|
||||||
{{else if eq .Type "reblog"}}
|
{{else if eq .Type "reblog"}}
|
||||||
<div class="retweet-info">
|
<div class="retweet-info">
|
||||||
<a class="img-link" href="/user/{{.Account.ID}}">
|
<a class="img-link" href="/user/{{.Account.ID}}" target="main">
|
||||||
<img class="status-profile-img" src="{{.Account.AvatarStatic}}" alt="avatar" />
|
<img class="status-profile-img" src="{{.Account.AvatarStatic}}" alt="avatar" />
|
||||||
</a>
|
</a>
|
||||||
<span class="status-dname"> {{EmojiFilter .Account.DisplayName .Account.Emojis}} </span>
|
<span class="status-dname"> {{EmojiFilter .Account.DisplayName .Account.Emojis}} </span>
|
||||||
@ -44,7 +55,7 @@
|
|||||||
|
|
||||||
{{else if eq .Type "favourite"}}
|
{{else if eq .Type "favourite"}}
|
||||||
<div class="retweet-info">
|
<div class="retweet-info">
|
||||||
<a class="img-link" href="/user/{{.Account.ID}}">
|
<a class="img-link" href="/user/{{.Account.ID}}" target="main">
|
||||||
<img class="status-profile-img" src="{{.Account.AvatarStatic}}" alt="avatar" />
|
<img class="status-profile-img" src="{{.Account.AvatarStatic}}" alt="avatar" />
|
||||||
</a>
|
</a>
|
||||||
<span class="status-dname"> {{EmojiFilter .Account.DisplayName .Account.Emojis}} </span>
|
<span class="status-dname"> {{EmojiFilter .Account.DisplayName .Account.Emojis}} </span>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
emoji list
|
emoji list
|
||||||
</a>
|
</a>
|
||||||
<div class="post-form-content-container">
|
<div class="post-form-content-container">
|
||||||
<textarea id="post-content" name="content" class="post-content" cols="50" rows="5">{{if .ReplyContext}}{{.ReplyContext.ReplyContent}}{{end}}</textarea>
|
<textarea id="post-content" name="content" class="post-content" cols="34" rows="5">{{if .ReplyContext}}{{.ReplyContext.ReplyContent}}{{end}}</textarea>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{if gt (len .Formats) 0}}
|
{{if gt (len .Formats) 0}}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}}
|
|
||||||
<div class="page-title"> Retweeted By </div>
|
<div class="page-title"> Retweeted By </div>
|
||||||
|
|
||||||
{{template "userlist.tmpl" (WithContext .Users $.Ctx)}}
|
{{template "userlist.tmpl" (WithContext .Users $.Ctx)}}
|
||||||
|
17
templates/root.tmpl
Normal file
17
templates/root.tmpl
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{{with .Data}}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset='utf-8'>
|
||||||
|
<meta content='width=device-width, initial-scale=1' name='viewport'>
|
||||||
|
<title>{{.Title}}</title>
|
||||||
|
</head>
|
||||||
|
<frameset cols="30%,*">
|
||||||
|
<frameset rows="316px,*">
|
||||||
|
<frame name="nav" class="nav-frame" src="/nav" />
|
||||||
|
<frame name="notification" class="notification-frame" src="/notifications" />
|
||||||
|
</frameset>
|
||||||
|
<frame name="main" class="main-frame" src="/timeline/home" />
|
||||||
|
</frameset>
|
||||||
|
</html>
|
||||||
|
{{end}}
|
@ -1,6 +1,5 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}}
|
|
||||||
<div class="page-title"> Search </div>
|
<div class="page-title"> Search </div>
|
||||||
|
|
||||||
<form class="search-form" action="/search" method="GET">
|
<form class="search-form" action="/search" method="GET">
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}}
|
|
||||||
<div class="page-title"> Settings </div>
|
<div class="page-title"> Settings </div>
|
||||||
|
|
||||||
<form id="settings-form" action="/settings" method="POST">
|
<form id="settings-form" action="/settings" method="POST">
|
||||||
@ -24,11 +23,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="settings-form-field">
|
<div class="settings-form-field">
|
||||||
<input id="mask-nsfw" name="mask_nsfw" type="checkbox" value="true" {{if .Settings.MaskNSFW}}checked{{end}}>
|
<input id="mask-nsfw" name="mask_nsfw" type="checkbox" value="true" {{if .Settings.MaskNSFW}}checked{{end}}>
|
||||||
<label for="mask-nsfw"> Mask NSFW Attachments </label>
|
<label for="mask-nsfw"> Mask NSFW attachments </label>
|
||||||
|
</div>
|
||||||
|
<div class="settings-form-field">
|
||||||
|
<input id="auto-refresh-notifications" name="auto_refresh_notifications" type="checkbox" value="true" {{if .Settings.AutoRefreshNotifications}}checked{{end}}>
|
||||||
|
<label for="auto-refresh-notifications"> Auto refresh notifications </label>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-form-field">
|
<div class="settings-form-field">
|
||||||
<input id="fluoride-mode" name="fluoride_mode" type="checkbox" value="true" {{if .Settings.FluorideMode}}checked{{end}}>
|
<input id="fluoride-mode" name="fluoride_mode" type="checkbox" value="true" {{if .Settings.FluorideMode}}checked{{end}}>
|
||||||
<label for="fluoride-mode"> Enable Fluoride Mode </label>
|
<label for="fluoride-mode"> Enable fluoride mode </label>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-form-field">
|
<div class="settings-form-field">
|
||||||
<input id="dark-mode" name="dark_mode" type="checkbox" value="true" {{if .Settings.DarkMode}}checked{{end}}>
|
<input id="dark-mode" name="dark_mode" type="checkbox" value="true" {{if .Settings.DarkMode}}checked{{end}}>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
<div class="page-title"> Signin </div>
|
<div class="page-title"> Signin </div>
|
||||||
|
|
||||||
<form class="signin-form" action="/signin" method="post">
|
<form class="signin-form" action="/signin" method="post">
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div id="status-{{.ID}}" class="status-container-container">
|
<div id="status-{{.ID}}" class="status-container-container">
|
||||||
{{if .Reblog}}
|
{{if .Reblog}}
|
||||||
<div class="retweet-info">
|
<div class="retweet-info">
|
||||||
<a class="img-link" href="/user/{{.Account.ID}}">
|
<a class="img-link" href="/user/{{.Account.ID}}" target="main">
|
||||||
<img class="status-profile-img" src="{{.Account.AvatarStatic}}" alt="avatar" />
|
<img class="status-profile-img" src="{{.Account.AvatarStatic}}" alt="avatar" />
|
||||||
</a>
|
</a>
|
||||||
<span class="status-dname"> {{EmojiFilter .Account.DisplayName .Account.Emojis}} </span>
|
<span class="status-dname"> {{EmojiFilter .Account.DisplayName .Account.Emojis}} </span>
|
||||||
@ -14,39 +14,39 @@
|
|||||||
{{with $s := .Data}}
|
{{with $s := .Data}}
|
||||||
<div class="status-container status-{{.ID}}" data-id="{{.ID}}">
|
<div class="status-container status-{{.ID}}" data-id="{{.ID}}">
|
||||||
<div class="status-profile-img-container">
|
<div class="status-profile-img-container">
|
||||||
<a class="img-link" href="/user/{{.Account.ID}}">
|
<a class="img-link" href="/user/{{.Account.ID}}" target="main">
|
||||||
<img class="status-profile-img" src="{{.Account.AvatarStatic}}" alt="avatar" />
|
<img class="status-profile-img" src="{{.Account.AvatarStatic}}" alt="avatar" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="status">
|
<div class="status">
|
||||||
<div class="status-name">
|
<div class="status-name">
|
||||||
<span class="status-dname"> {{EmojiFilter .Account.DisplayName .Account.Emojis}} </span>
|
<span class="status-dname"> {{EmojiFilter .Account.DisplayName .Account.Emojis}} </span>
|
||||||
<a href="/user/{{.Account.ID}}" >
|
<a href="/user/{{.Account.ID}}" target="main">
|
||||||
<span class="status-uname"> {{.Account.Acct}} </span>
|
<span class="status-uname"> {{.Account.Acct}} </span>
|
||||||
</a>
|
</a>
|
||||||
<div class="more-container" title="more">
|
<div class="more-container">
|
||||||
<div class="remote-link">
|
<div class="remote-link">
|
||||||
{{.Visibility}}
|
{{.Visibility}}
|
||||||
</div>
|
</div>
|
||||||
<div class="more-content">
|
<div class="more-content">
|
||||||
<a class="more-link" href="{{.URL}}" target="_blank" title="source">
|
<a class="more-link" href="{{.URL}}" target="_blank">
|
||||||
source
|
source
|
||||||
</a>
|
</a>
|
||||||
{{if .Muted}}
|
{{if .Muted}}
|
||||||
<form action="/unmuteconv/{{.ID}}" method="post">
|
<form action="/unmuteconv/{{.ID}}" method="post">
|
||||||
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
||||||
<input type="submit" value="unmute" class="btn-link more-link" title="unmute">
|
<input type="submit" value="unmute" class="btn-link more-link">
|
||||||
</form>
|
</form>
|
||||||
{{else}}
|
{{else}}
|
||||||
<form action="/muteconv/{{.ID}}" method="post">
|
<form action="/muteconv/{{.ID}}" method="post">
|
||||||
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
||||||
<input type="submit" value="mute" class="btn-link more-link" title="mute">
|
<input type="submit" value="mute" class="btn-link more-link">
|
||||||
</form>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if eq $.Ctx.UserID .Account.ID}}
|
{{if eq $.Ctx.UserID .Account.ID}}
|
||||||
<form action="/delete/{{.ID}}" method="post">
|
<form action="/delete/{{.ID}}" method="post">
|
||||||
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
||||||
<input type="submit" value="delete" class="btn-link more-link" title="delete">
|
<input type="submit" value="delete" class="btn-link more-link">
|
||||||
</form>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
@ -55,7 +55,7 @@
|
|||||||
<div class="status-reply-container">
|
<div class="status-reply-container">
|
||||||
{{if .InReplyToID}}
|
{{if .InReplyToID}}
|
||||||
<div class="status-reply-to">
|
<div class="status-reply-to">
|
||||||
<a class="status-reply-to-link" href="{{if not .ShowReplies}}/thread/{{.InReplyToID}}{{end}}#status-{{.InReplyToID}}">
|
<a class="status-reply-to-link" href="{{if not .ShowReplies}}/thread/{{.InReplyToID}}{{end}}#status-{{.InReplyToID}}" target="main">
|
||||||
reply to {{.Pleroma.InReplyToAccountAcct}}
|
reply to {{.Pleroma.InReplyToAccountAcct}}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -139,16 +139,16 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
<div class="status-action-container">
|
<div class="status-action-container">
|
||||||
<div class="status-action">
|
<div class="status-action">
|
||||||
<a href="/thread/{{.ID}}?reply=true#status-{{.ID}}" title="reply">
|
<a href="/thread/{{.ID}}?reply=true#status-{{.ID}}" target="main">
|
||||||
reply
|
reply
|
||||||
</a>
|
</a>
|
||||||
<a class="status-reply-count" href="/thread/{{.ID}}#status-{{.ID}}" {{if $.Ctx.ThreadInNewTab}}target="_blank"{{end}}>
|
<a class="status-reply-count" href="/thread/{{.ID}}#status-{{.ID}}" target="{{if $.Ctx.ThreadInNewTab}}_blank{{else}}main{{end}}">
|
||||||
{{if .RepliesCount}} ({{DisplayInteractionCount .RepliesCount}}) {{end}}
|
{{if .RepliesCount}} ({{DisplayInteractionCount .RepliesCount}}) {{end}}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-action">
|
<div class="status-action">
|
||||||
{{if or (eq .Visibility "private") (eq .Visibility "direct")}}
|
{{if or (eq .Visibility "private") (eq .Visibility "direct")}}
|
||||||
<a class="status-retweet" title="this status cannot be retweeted">
|
<a class="status-retweet" href="" title="this status cannot be retweeted" target="main">
|
||||||
retweet
|
retweet
|
||||||
</a>
|
</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
@ -156,17 +156,17 @@
|
|||||||
<form class="status-retweet" data-action="unretweet" action="/unretweet/{{.ID}}" method="post">
|
<form class="status-retweet" data-action="unretweet" action="/unretweet/{{.ID}}" method="post">
|
||||||
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
||||||
<input type="hidden" name="retweeted_by_id" value="{{.RetweetedByID}}">
|
<input type="hidden" name="retweeted_by_id" value="{{.RetweetedByID}}">
|
||||||
<input type="submit" value="unretweet" class="btn-link" title="unretweet">
|
<input type="submit" value="unretweet" class="btn-link">
|
||||||
</form>
|
</form>
|
||||||
{{else}}
|
{{else}}
|
||||||
<form class="status-retweet" data-action="retweet" action="/retweet/{{.ID}}" method="post">
|
<form class="status-retweet" data-action="retweet" action="/retweet/{{.ID}}" method="post">
|
||||||
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
||||||
<input type="hidden" name="retweeted_by_id" value="{{.RetweetedByID}}">
|
<input type="hidden" name="retweeted_by_id" value="{{.RetweetedByID}}">
|
||||||
<input type="submit" value="retweet" class="btn-link" title="retweet">
|
<input type="submit" value="retweet" class="btn-link">
|
||||||
</form>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
<a class="status-retweet-count" href="/retweetedby/{{.ID}}" title="click to see the the list">
|
<a class="status-retweet-count" href="/retweetedby/{{.ID}}" title="click to see the the list" target="main">
|
||||||
{{if .ReblogsCount}} ({{DisplayInteractionCount .ReblogsCount}}) {{end}}
|
{{if .ReblogsCount}} ({{DisplayInteractionCount .ReblogsCount}}) {{end}}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -175,22 +175,22 @@
|
|||||||
<form class="status-like" data-action="unlike" action="/unlike/{{.ID}}" method="post">
|
<form class="status-like" data-action="unlike" action="/unlike/{{.ID}}" method="post">
|
||||||
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
||||||
<input type="hidden" name="retweeted_by_id" value="{{.RetweetedByID}}">
|
<input type="hidden" name="retweeted_by_id" value="{{.RetweetedByID}}">
|
||||||
<input type="submit" value="unlike" class="btn-link" title="unlike">
|
<input type="submit" value="unlike" class="btn-link">
|
||||||
</form>
|
</form>
|
||||||
{{else}}
|
{{else}}
|
||||||
<form class="status-like" data-action="like" action="/like/{{.ID}}" method="post">
|
<form class="status-like" data-action="like" action="/like/{{.ID}}" method="post">
|
||||||
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
<input type="hidden" name="csrf_token" value="{{$.Ctx.CSRFToken}}">
|
||||||
<input type="hidden" name="retweeted_by_id" value="{{.RetweetedByID}}">
|
<input type="hidden" name="retweeted_by_id" value="{{.RetweetedByID}}">
|
||||||
<input type="submit" value="like" class="btn-link" title="like">
|
<input type="submit" value="like" class="btn-link">
|
||||||
</form>
|
</form>
|
||||||
{{end}}
|
{{end}}
|
||||||
<a class="status-like-count" href="/likedby/{{.ID}}" title="click to see the the list">
|
<a class="status-like-count" href="/likedby/{{.ID}}" title="click to see the the list" target="main">
|
||||||
{{if .FavouritesCount}} ({{DisplayInteractionCount .FavouritesCount}}) {{end}}
|
{{if .FavouritesCount}} ({{DisplayInteractionCount .FavouritesCount}}) {{end}}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-action">
|
<div class="status-action">
|
||||||
<a class="status-time" href="{{if not .ShowReplies}}/thread/{{.ID}}{{end}}#status-{{.ID}}"
|
<a class="status-time" href="{{if not .ShowReplies}}/thread/{{.ID}}{{end}}#status-{{.ID}}"
|
||||||
{{if $.Ctx.ThreadInNewTab}}target="_blank"{{end}}>
|
target="{{if $.Ctx.ThreadInNewTab}}_blank{{else}}main{{end}}">
|
||||||
<time datetime="{{FormatTimeRFC3339 .CreatedAt}}" title="{{FormatTimeRFC822 .CreatedAt}}">
|
<time datetime="{{FormatTimeRFC3339 .CreatedAt}}" title="{{FormatTimeRFC822 .CreatedAt}}">
|
||||||
{{TimeSince .CreatedAt}}
|
{{TimeSince .CreatedAt}}
|
||||||
</time>
|
</time>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{{with $s := .Data}}
|
{{with $s := .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}}
|
|
||||||
<div class="page-title"> Thread </div>
|
<div class="page-title"> Thread </div>
|
||||||
|
|
||||||
{{range .Statuses}}
|
{{range .Statuses}}
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}}
|
|
||||||
<div class="page-title"> {{.Title}} </div>
|
<div class="page-title"> {{.Title}} </div>
|
||||||
|
|
||||||
{{template "postform.tmpl" (WithContext .PostContext $.Ctx)}}
|
|
||||||
|
|
||||||
{{range .Statuses}}
|
{{range .Statuses}}
|
||||||
{{template "status.tmpl" (WithContext . $.Ctx)}}
|
{{template "status.tmpl" (WithContext . $.Ctx)}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}}
|
|
||||||
<div class="page-title"> User </div>
|
<div class="page-title"> User </div>
|
||||||
|
|
||||||
<div class="user-info-container">
|
<div class="user-info-container">
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{{with .Data}}
|
{{with .Data}}
|
||||||
{{template "header.tmpl" (WithContext .HeaderData $.Ctx)}}
|
{{template "header.tmpl" (WithContext .CommonData $.Ctx)}}
|
||||||
{{template "navigation.tmpl" (WithContext .NavbarData $.Ctx)}}
|
|
||||||
<div class="page-title"> Search {{EmojiFilter .User.DisplayName .User.Emojis}}'s statuses </div>
|
<div class="page-title"> Search {{EmojiFilter .User.DisplayName .User.Emojis}}'s statuses </div>
|
||||||
|
|
||||||
<form class="search-form" action="/usersearch/{{.User.ID}}" method="GET">
|
<form class="search-form" action="/usersearch/{{.User.ID}}" method="GET">
|
||||||
|
Loading…
Reference in New Issue
Block a user