Begin work on making the analytics panes somewhat usable when having JavaScript disabled.
Very minor refactoring here and there across the software. Save some allocations here and there.
This commit is contained in:
parent
7b09a3aff5
commit
4d9dc76392
|
@ -18,10 +18,11 @@ type DefaultActivityStream struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefaultActivityStream(acc *qgen.Accumulator) (*DefaultActivityStream, error) {
|
func NewDefaultActivityStream(acc *qgen.Accumulator) (*DefaultActivityStream, error) {
|
||||||
|
as := "activity_stream"
|
||||||
return &DefaultActivityStream{
|
return &DefaultActivityStream{
|
||||||
add: acc.Insert("activity_stream").Columns("actor, targetUser, event, elementType, elementID, createdAt").Fields("?,?,?,?,?,UTC_TIMESTAMP()").Prepare(),
|
add: acc.Insert(as).Columns("actor, targetUser, event, elementType, elementID, createdAt").Fields("?,?,?,?,?,UTC_TIMESTAMP()").Prepare(),
|
||||||
get: acc.Select("activity_stream").Columns("actor, targetUser, event, elementType, elementID, createdAt").Where("asid = ?").Prepare(),
|
get: acc.Select(as).Columns("actor, targetUser, event, elementType, elementID, createdAt").Where("asid = ?").Prepare(),
|
||||||
count: acc.Count("activity_stream").Prepare(),
|
count: acc.Count(as).Prepare(),
|
||||||
}, acc.FirstError()
|
}, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ func init() {
|
||||||
qgen.DBInsert{"activity_stream_matches", "watcher, asid", ""},
|
qgen.DBInsert{"activity_stream_matches", "watcher, asid", ""},
|
||||||
qgen.DBJoin{"activity_stream", "activity_subscriptions", "activity_subscriptions.user, activity_stream.asid", "activity_subscriptions.targetType = activity_stream.elementType AND activity_subscriptions.targetID = activity_stream.elementID AND activity_subscriptions.user != activity_stream.actor", "asid = ?", "", ""},
|
qgen.DBJoin{"activity_stream", "activity_subscriptions", "activity_subscriptions.user, activity_stream.asid", "activity_subscriptions.targetType = activity_stream.elementType AND activity_subscriptions.targetID = activity_stream.elementID AND activity_subscriptions.user != activity_stream.actor", "asid = ?", "", ""},
|
||||||
),
|
),
|
||||||
notifyOne: acc.Insert("activity_stream_matches").Columns("watcher, asid").Fields("?,?").Prepare(),
|
notifyOne: acc.Insert("activity_stream_matches").Columns("watcher,asid").Fields("?,?").Prepare(),
|
||||||
getWatchers: acc.SimpleInnerJoin("activity_stream", "activity_subscriptions", "activity_subscriptions.user", "activity_subscriptions.targetType = activity_stream.elementType AND activity_subscriptions.targetID = activity_stream.elementID AND activity_subscriptions.user != activity_stream.actor", "asid = ?", "", ""),
|
getWatchers: acc.SimpleInnerJoin("activity_stream", "activity_subscriptions", "activity_subscriptions.user", "activity_subscriptions.targetType = activity_stream.elementType AND activity_subscriptions.targetID = activity_stream.elementID AND activity_subscriptions.user != activity_stream.actor", "asid = ?", "", ""),
|
||||||
}
|
}
|
||||||
return acc.FirstError()
|
return acc.FirstError()
|
||||||
|
@ -224,8 +224,7 @@ func notifyWatchers(asid int) {
|
||||||
}
|
}
|
||||||
uids = append(uids, uid)
|
uids = append(uids, uid)
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
if err = rows.Err(); err != nil {
|
||||||
if err != nil {
|
|
||||||
LogError(err)
|
LogError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Gosora Authentication Interface
|
* Gosora Authentication Interface
|
||||||
* Copyright Azareal 2017 - 2019
|
* Copyright Azareal 2017 - 2020
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package common
|
package common
|
||||||
|
@ -145,6 +145,7 @@ func (auth *DefaultAuth) ValidateMFAToken(mfaToken string, uid int) error {
|
||||||
if ok {
|
if ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, scratch := range mfaItem.Scratch {
|
for i, scratch := range mfaItem.Scratch {
|
||||||
if subtle.ConstantTimeCompare([]byte(scratch), []byte(mfaToken)) == 1 {
|
if subtle.ConstantTimeCompare([]byte(scratch), []byte(mfaToken)) == 1 {
|
||||||
err = mfaItem.BurnScratch(i)
|
err = mfaItem.BurnScratch(i)
|
||||||
|
@ -155,6 +156,7 @@ func (auth *DefaultAuth) ValidateMFAToken(mfaToken string, uid int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrWrongMFAToken
|
return ErrWrongMFAToken
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,10 @@ type MemoryForumPermsStore struct {
|
||||||
|
|
||||||
func NewMemoryForumPermsStore() (*MemoryForumPermsStore, error) {
|
func NewMemoryForumPermsStore() (*MemoryForumPermsStore, error) {
|
||||||
acc := qgen.NewAcc()
|
acc := qgen.NewAcc()
|
||||||
|
fp := "forums_permissions"
|
||||||
return &MemoryForumPermsStore{
|
return &MemoryForumPermsStore{
|
||||||
getByForum: acc.Select("forums_permissions").Columns("gid, permissions").Where("fid = ?").Orderby("gid ASC").Prepare(),
|
getByForum: acc.Select(fp).Columns("gid, permissions").Where("fid = ?").Orderby("gid ASC").Prepare(),
|
||||||
getByForumGroup: acc.Select("forums_permissions").Columns("permissions").Where("fid = ? AND gid = ?").Prepare(),
|
getByForumGroup: acc.Select(fp).Columns("permissions").Where("fid = ? AND gid = ?").Prepare(),
|
||||||
|
|
||||||
evenForums: make(map[int]map[int]*ForumPerms),
|
evenForums: make(map[int]map[int]*ForumPerms),
|
||||||
oddForums: make(map[int]map[int]*ForumPerms),
|
oddForums: make(map[int]map[int]*ForumPerms),
|
||||||
|
|
|
@ -138,8 +138,9 @@ func (s *MemoryPollCache) RemoveUnsafe(id int) error {
|
||||||
|
|
||||||
// Flush removes all the polls from the cache, useful for tests.
|
// Flush removes all the polls from the cache, useful for tests.
|
||||||
func (s *MemoryPollCache) Flush() {
|
func (s *MemoryPollCache) Flush() {
|
||||||
|
m := make(map[int]*Poll)
|
||||||
s.Lock()
|
s.Lock()
|
||||||
s.items = make(map[int]*Poll)
|
s.items = m
|
||||||
s.length = 0
|
s.length = 0
|
||||||
s.Unlock()
|
s.Unlock()
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,10 +45,11 @@ var settingStmts SettingStmts
|
||||||
func init() {
|
func init() {
|
||||||
SettingBox.Store(SettingMap(make(map[string]interface{})))
|
SettingBox.Store(SettingMap(make(map[string]interface{})))
|
||||||
DbInits.Add(func(acc *qgen.Accumulator) error {
|
DbInits.Add(func(acc *qgen.Accumulator) error {
|
||||||
|
s := "settings"
|
||||||
settingStmts = SettingStmts{
|
settingStmts = SettingStmts{
|
||||||
getAll: acc.Select("settings").Columns("name, content, type, constraints").Prepare(),
|
getAll: acc.Select(s).Columns("name, content, type, constraints").Prepare(),
|
||||||
get: acc.Select("settings").Columns("content, type, constraints").Where("name = ?").Prepare(),
|
get: acc.Select(s).Columns("content, type, constraints").Where("name = ?").Prepare(),
|
||||||
update: acc.Update("settings").Set("content = ?").Where("name = ?").Prepare(),
|
update: acc.Update(s).Set("content = ?").Where("name = ?").Prepare(),
|
||||||
}
|
}
|
||||||
return acc.FirstError()
|
return acc.FirstError()
|
||||||
})
|
})
|
||||||
|
@ -67,8 +68,8 @@ func LoadSettings() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, setting := range settings {
|
for _, s := range settings {
|
||||||
err = sBox.ParseSetting(setting.Name, setting.Content, setting.Type, setting.Constraint)
|
err = sBox.ParseSetting(s.Name, s.Content, s.Type, s.Constraint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -80,7 +81,7 @@ func LoadSettings() error {
|
||||||
|
|
||||||
// TODO: Add better support for HTML attributes (html-attribute). E.g. Meta descriptions.
|
// TODO: Add better support for HTML attributes (html-attribute). E.g. Meta descriptions.
|
||||||
func (sBox SettingMap) ParseSetting(sname string, scontent string, stype string, constraint string) (err error) {
|
func (sBox SettingMap) ParseSetting(sname string, scontent string, stype string, constraint string) (err error) {
|
||||||
var ssBox = map[string]interface{}(sBox)
|
ssBox := map[string]interface{}(sBox)
|
||||||
switch stype {
|
switch stype {
|
||||||
case "bool":
|
case "bool":
|
||||||
ssBox[sname] = (scontent == "1")
|
ssBox[sname] = (scontent == "1")
|
||||||
|
|
|
@ -88,7 +88,7 @@ func (tList *DefaultTopicList) Tick() error {
|
||||||
canSee[i] = byte(item)
|
canSee[i] = byte(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
var canSeeInt = make([]int, len(canSee))
|
canSeeInt := make([]int, len(canSee))
|
||||||
copy(canSeeInt, group.CanSee)
|
copy(canSeeInt, group.CanSee)
|
||||||
sCanSee := string(canSee)
|
sCanSee := string(canSee)
|
||||||
permTree[sCanSee] = canSeeInt
|
permTree[sCanSee] = canSeeInt
|
||||||
|
@ -161,7 +161,7 @@ func (tList *DefaultTopicList) GetListByCanSee(canSee []int, page int, orderby s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var inSlice = func(haystack []int, needle int) bool {
|
inSlice := func(haystack []int, needle int) bool {
|
||||||
for _, item := range haystack {
|
for _, item := range haystack {
|
||||||
if needle == item {
|
if needle == item {
|
||||||
return true
|
return true
|
||||||
|
@ -200,7 +200,7 @@ func (tList *DefaultTopicList) GetList(page int, orderby string, filterIDs []int
|
||||||
return nil, nil, Paginator{nil, 1, 1}, err
|
return nil, nil, Paginator{nil, 1, 1}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var inSlice = func(haystack []int, needle int) bool {
|
inSlice := func(haystack []int, needle int) bool {
|
||||||
for _, item := range haystack {
|
for _, item := range haystack {
|
||||||
if needle == item {
|
if needle == item {
|
||||||
return true
|
return true
|
||||||
|
@ -282,43 +282,43 @@ func (tList *DefaultTopicList) getList(page int, orderby string, argList []inter
|
||||||
reqUserList := make(map[int]bool)
|
reqUserList := make(map[int]bool)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
// TODO: Embed Topic structs in TopicsRow to make it easier for us to reuse this work in the topic cache
|
// TODO: Embed Topic structs in TopicsRow to make it easier for us to reuse this work in the topic cache
|
||||||
topic := TopicsRow{}
|
t := TopicsRow{}
|
||||||
err := rows.Scan(&topic.ID, &topic.Title, &topic.Content, &topic.CreatedBy, &topic.IsClosed, &topic.Sticky, &topic.CreatedAt, &topic.LastReplyAt, &topic.LastReplyBy, &topic.LastReplyID, &topic.ParentID, &topic.ViewCount, &topic.PostCount, &topic.LikeCount, &topic.AttachCount, &topic.Poll, &topic.Data)
|
err := rows.Scan(&t.ID, &t.Title, &t.Content, &t.CreatedBy, &t.IsClosed, &t.Sticky, &t.CreatedAt, &t.LastReplyAt, &t.LastReplyBy, &t.LastReplyID, &t.ParentID, &t.ViewCount, &t.PostCount, &t.LikeCount, &t.AttachCount, &t.Poll, &t.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, Paginator{nil, 1, 1}, err
|
return nil, Paginator{nil, 1, 1}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
topic.Link = BuildTopicURL(NameToSlug(topic.Title), topic.ID)
|
t.Link = BuildTopicURL(NameToSlug(t.Title), t.ID)
|
||||||
// TODO: Pass forum to something like topicItem.Forum and use that instead of these two properties? Could be more flexible.
|
// TODO: Pass forum to something like topicItem.Forum and use that instead of these two properties? Could be more flexible.
|
||||||
forum := Forums.DirtyGet(topic.ParentID)
|
forum := Forums.DirtyGet(t.ParentID)
|
||||||
topic.ForumName = forum.Name
|
t.ForumName = forum.Name
|
||||||
topic.ForumLink = forum.Link
|
t.ForumLink = forum.Link
|
||||||
|
|
||||||
// TODO: Create a specialised function with a bit less overhead for getting the last page for a post count
|
// TODO: Create a specialised function with a bit less overhead for getting the last page for a post count
|
||||||
_, _, lastPage := PageOffset(topic.PostCount, 1, Config.ItemsPerPage)
|
_, _, lastPage := PageOffset(t.PostCount, 1, Config.ItemsPerPage)
|
||||||
topic.LastPage = lastPage
|
t.LastPage = lastPage
|
||||||
|
|
||||||
// TODO: Rename this Vhook to better reflect moving the topic list from /routes/ to /common/
|
// TODO: Rename this Vhook to better reflect moving the topic list from /routes/ to /common/
|
||||||
GetHookTable().Vhook("topics_topic_row_assign", &topic, &forum)
|
GetHookTable().Vhook("topics_topic_row_assign", &t, &forum)
|
||||||
topicList = append(topicList, &topic)
|
topicList = append(topicList, &t)
|
||||||
reqUserList[topic.CreatedBy] = true
|
reqUserList[t.CreatedBy] = true
|
||||||
reqUserList[topic.LastReplyBy] = true
|
reqUserList[t.LastReplyBy] = true
|
||||||
|
|
||||||
//log.Print("rlen: ", rlen)
|
//log.Print("rlen: ", rlen)
|
||||||
//log.Print("rcap: ", rcap)
|
//log.Print("rcap: ", rcap)
|
||||||
//log.Print("topic.PostCount: ", topic.PostCount)
|
//log.Print("topic.PostCount: ", t.PostCount)
|
||||||
//log.Print("topic.PostCount == 2 && rlen < rcap: ", topic.PostCount == 2 && rlen < rcap)
|
//log.Print("topic.PostCount == 2 && rlen < rcap: ", topic.PostCount == 2 && rlen < rcap)
|
||||||
|
|
||||||
// Avoid the extra queries on topic list pages, if we already have what we want...
|
// Avoid the extra queries on topic list pages, if we already have what we want...
|
||||||
var hRids = false
|
hRids := false
|
||||||
if tcache != nil {
|
if tcache != nil {
|
||||||
if t, err := tcache.Get(topic.ID); err == nil {
|
if t, err := tcache.Get(t.ID); err == nil {
|
||||||
hRids = len(t.Rids) != 0
|
hRids = len(t.Rids) != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if topic.PostCount == 2 && rlen < rcap && !hRids && page < 5 {
|
if t.PostCount == 2 && rlen < rcap && !hRids && page < 5 {
|
||||||
rids, err := GetRidsForTopic(topic.ID, 0)
|
rids, err := GetRidsForTopic(t.ID, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, Paginator{nil, 1, 1}, err
|
return nil, Paginator{nil, 1, 1}, err
|
||||||
}
|
}
|
||||||
|
@ -329,12 +329,12 @@ func (tList *DefaultTopicList) getList(page int, orderby string, argList []inter
|
||||||
}
|
}
|
||||||
_, _ = Rstore.Get(rids[0])
|
_, _ = Rstore.Get(rids[0])
|
||||||
rlen++
|
rlen++
|
||||||
topic.Rids = []int{rids[0]}
|
t.Rids = []int{rids[0]}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tcache != nil {
|
if tcache != nil {
|
||||||
if _, err := tcache.Get(topic.ID); err == sql.ErrNoRows {
|
if _, err := tcache.Get(t.ID); err == sql.ErrNoRows {
|
||||||
_ = tcache.Set(topic.Topic())
|
_ = tcache.Set(t.Topic())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ func (tList *DefaultTopicList) getList(page int, orderby string, argList []inter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the user ID map to a slice, then bulk load the users
|
// Convert the user ID map to a slice, then bulk load the users
|
||||||
var idSlice = make([]int, len(reqUserList))
|
idSlice := make([]int, len(reqUserList))
|
||||||
var i int
|
var i int
|
||||||
for userID := range reqUserList {
|
for userID := range reqUserList {
|
||||||
idSlice[i] = userID
|
idSlice[i] = userID
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright Azareal 2017 - 2019 */
|
/* Copyright Azareal 2017 - 2020 */
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -223,6 +223,7 @@ func (h *WsHubImpl) UserCount() (count int) {
|
||||||
h.evenUserLock.RLock()
|
h.evenUserLock.RLock()
|
||||||
count += len(h.evenOnlineUsers)
|
count += len(h.evenOnlineUsers)
|
||||||
h.evenUserLock.RUnlock()
|
h.evenUserLock.RUnlock()
|
||||||
|
|
||||||
h.oddUserLock.RLock()
|
h.oddUserLock.RLock()
|
||||||
count += len(h.oddOnlineUsers)
|
count += len(h.oddOnlineUsers)
|
||||||
h.oddUserLock.RUnlock()
|
h.oddUserLock.RUnlock()
|
||||||
|
@ -236,6 +237,7 @@ func (h *WsHubImpl) HasUser(uid int) (exists bool) {
|
||||||
if exists {
|
if exists {
|
||||||
return exists
|
return exists
|
||||||
}
|
}
|
||||||
|
|
||||||
h.oddUserLock.RLock()
|
h.oddUserLock.RLock()
|
||||||
_, exists = h.oddOnlineUsers[uid]
|
_, exists = h.oddOnlineUsers[uid]
|
||||||
h.oddUserLock.RUnlock()
|
h.oddUserLock.RUnlock()
|
||||||
|
|
|
@ -100,6 +100,7 @@ func (u *WSUser) AddSocket(conn *websocket.Conn, page string) {
|
||||||
|
|
||||||
func (u *WSUser) RemoveSocket(conn *websocket.Conn) {
|
func (u *WSUser) RemoveSocket(conn *websocket.Conn) {
|
||||||
u.Lock()
|
u.Lock()
|
||||||
|
defer u.Unlock()
|
||||||
if len(u.Sockets) < 6 {
|
if len(u.Sockets) < 6 {
|
||||||
for i, socket := range u.Sockets {
|
for i, socket := range u.Sockets {
|
||||||
if socket == nil {
|
if socket == nil {
|
||||||
|
@ -107,7 +108,6 @@ func (u *WSUser) RemoveSocket(conn *websocket.Conn) {
|
||||||
}
|
}
|
||||||
if socket.conn == conn {
|
if socket.conn == conn {
|
||||||
u.Sockets[i] = nil
|
u.Sockets[i] = nil
|
||||||
u.Unlock()
|
|
||||||
//fmt.Printf("%+v\n", wsUser.Sockets)
|
//fmt.Printf("%+v\n", wsUser.Sockets)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -123,8 +123,6 @@ func (u *WSUser) RemoveSocket(conn *websocket.Conn) {
|
||||||
}
|
}
|
||||||
u.Sockets = append(u.Sockets[:key], u.Sockets[key+1:]...)
|
u.Sockets = append(u.Sockets[:key], u.Sockets[key+1:]...)
|
||||||
//fmt.Printf("%+v\n", u.Sockets)
|
//fmt.Printf("%+v\n", u.Sockets)
|
||||||
|
|
||||||
u.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *WSUser) SetPageForSocket(conn *websocket.Conn, page string) error {
|
func (u *WSUser) SetPageForSocket(conn *websocket.Conn, page string) error {
|
||||||
|
|
|
@ -87,8 +87,8 @@ type Member struct {
|
||||||
User c.User
|
User c.User
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrebuildTmplList(user c.User, header *c.Header) c.CTmpl {
|
func PrebuildTmplList(user c.User, h *c.Header) c.CTmpl {
|
||||||
var guildList = []*Guild{
|
guildList := []*Guild{
|
||||||
&Guild{
|
&Guild{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
Name: "lol",
|
Name: "lol",
|
||||||
|
@ -104,7 +104,7 @@ func PrebuildTmplList(user c.User, header *c.Header) c.CTmpl {
|
||||||
Forums: []*c.Forum{c.Forums.DirtyGet(1)},
|
Forums: []*c.Forum{c.Forums.DirtyGet(1)},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
listPage := ListPage{"Guild List", user, header, guildList}
|
listPage := ListPage{"Guild List", user, h, guildList}
|
||||||
return c.CTmpl{"guilds_guild_list", "guilds_guild_list.html", "templates/", "guilds.ListPage", listPage, []string{"./extend/guilds/lib"}}
|
return c.CTmpl{"guilds_guild_list", "guilds_guild_list.html", "templates/", "guilds.ListPage", listPage, []string{"./extend/guilds/lib"}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -879,7 +879,7 @@ function mainInit(){
|
||||||
for(let i = 0; i < elems.length; i++) {
|
for(let i = 0; i < elems.length; i++) {
|
||||||
let elem = elems[i];
|
let elem = elems[i];
|
||||||
if(elem.nodeName=="SELECT") {
|
if(elem.nodeName=="SELECT") {
|
||||||
s += elem.name + "=" + elem.options[elem.selectedIndex].getAttribute("val") + "&";
|
s += elem.name + "=" + elem.options[elem.selectedIndex].getAttribute("value") + "&";
|
||||||
}
|
}
|
||||||
// TODO: Implement other element types...
|
// TODO: Implement other element types...
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ type RouteSubset struct {
|
||||||
|
|
||||||
func (set *RouteSubset) Before(lines ...string) *RouteSubset {
|
func (set *RouteSubset) Before(lines ...string) *RouteSubset {
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
for _, route := range set.RouteList {
|
for _, r := range set.RouteList {
|
||||||
route.RunBefore = append(route.RunBefore, Runnable{line, false})
|
r.RunBefore = append(r.RunBefore, Runnable{line, false})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return set
|
return set
|
||||||
|
@ -15,8 +15,8 @@ func (set *RouteSubset) Before(lines ...string) *RouteSubset {
|
||||||
|
|
||||||
func (set *RouteSubset) LitBefore(lines ...string) *RouteSubset {
|
func (set *RouteSubset) LitBefore(lines ...string) *RouteSubset {
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
for _, route := range set.RouteList {
|
for _, r := range set.RouteList {
|
||||||
route.RunBefore = append(route.RunBefore, Runnable{line, true})
|
r.RunBefore = append(r.RunBefore, Runnable{line, true})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return set
|
return set
|
||||||
|
|
|
@ -103,7 +103,7 @@ func SettingEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, snam
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
scontent := c.SanitiseBody(r.PostFormValue("setting-value"))
|
scontent := c.SanitiseBody(r.PostFormValue("value"))
|
||||||
rerr := headerLite.Settings.Update(sname, scontent)
|
rerr := headerLite.Settings.Update(sname, scontent)
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
|
|
|
@ -13,4 +13,4 @@
|
||||||
<div class="rowitem passive"><a href="/user/convos/">{{lang "account_menu_messages"}}</a></div>
|
<div class="rowitem passive"><a href="/user/convos/">{{lang "account_menu_messages"}}</a></div>
|
||||||
{{/** TODO: Add an alerts page with pagination to go through alerts which either don't fit in the alerts drop-down or which have already been dismissed. Bear in mind though that dismissed alerts older than two weeks might be purged to save space and to speed up the database **/}}
|
{{/** TODO: Add an alerts page with pagination to go through alerts which either don't fit in the alerts drop-down or which have already been dismissed. Bear in mind though that dismissed alerts older than two weeks might be purged to save space and to speed up the database **/}}
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
|
@ -24,7 +24,7 @@
|
||||||
<div class="levelBit">
|
<div class="levelBit">
|
||||||
<a href="/user/levels/">{{level .CurrentUser.Level}}</a>
|
<a href="/user/levels/">{{level .CurrentUser.Level}}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="progressWrap" style="width: {{.Percentage}}%;">
|
<div class="progressWrap" style="width:{{.Percentage}}%;">
|
||||||
<div>{{.CurrentScore}} / {{.NextScore}}</div>
|
<div>{{.CurrentScore}} / {{.NextScore}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -20,10 +20,8 @@
|
||||||
<div class="rowitem rowmsg" style="white-space:pre-wrap;">{{lang "account_mfa_scratch_explanation"}}</div>
|
<div class="rowitem rowmsg" style="white-space:pre-wrap;">{{lang "account_mfa_scratch_explanation"}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_mfa_scratches" class="colstack_item rowlist">
|
<div id="panel_mfa_scratches" class="colstack_item rowlist">
|
||||||
{{range .Something}}
|
{{range .Something}}<div class="rowitem">{{.}}</div>{{end}}
|
||||||
<div class="rowitem">{{.}}</div>
|
|
||||||
{{end}}
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
{{template "footer.html" . }}
|
{{template "footer.html" . }}
|
|
@ -23,4 +23,4 @@
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
{{template "footer.html" . }}
|
{{template "footer.html" . }}
|
|
@ -18,9 +18,9 @@
|
||||||
<div class="formitem formlabel"><a>Visibility</a></div>
|
<div class="formitem formlabel"><a>Visibility</a></div>
|
||||||
<div class="formitem">
|
<div class="formitem">
|
||||||
<select name="group_privacy">
|
<select name="group_privacy">
|
||||||
<option val="0">Public</option>
|
<option value=0>Public</option>
|
||||||
<option val="1">Protected</option>
|
<option value=1>Protected</option>
|
||||||
<option val="2">Private</option>
|
<option value=2>Private</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,4 +31,4 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
{{template "footer.html" . }}
|
{{template "footer.html" . }}
|
|
@ -29,12 +29,12 @@
|
||||||
top: 4px;
|
top: 4px;
|
||||||
}
|
}
|
||||||
.menuItem a {
|
.menuItem a {
|
||||||
color: black;
|
color: black;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.rightMenu {
|
.rightMenu {
|
||||||
float: right;
|
float: right;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
border-left: 1px solid #ccc;
|
border-left: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
.sgBackdrop {
|
.sgBackdrop {
|
||||||
|
@ -45,4 +45,4 @@
|
||||||
padding-top: calc(150px - 38px);
|
padding-top: calc(150px - 38px);
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -16,12 +16,12 @@
|
||||||
<div class="menuItem rightMenu"><a href="#">Edit</a></div>
|
<div class="menuItem rightMenu"><a href="#">Edit</a></div>
|
||||||
<div class="menuItem rightMenu"><a href="/guild/join/{{.Guild.ID}}">Join</a></div>
|
<div class="menuItem rightMenu"><a href="/guild/join/{{.Guild.ID}}">Join</a></div>
|
||||||
</nav>
|
</nav>
|
||||||
<div style="clear: both;"></div>
|
<div style="clear:both;"></div>
|
||||||
</div>
|
</div>
|
||||||
<main id="socialgroups_member_list" class="rowblock member_list" style="position: relative;z-index: 50;">
|
<main id="socialgroups_member_list" class="rowblock member_list" style="position:relative;z-index:50;">
|
||||||
{{range .ItemList}}<div class="rowitem passive datarow" style="background-image: url({{.User.Avatar}});background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 78px;{{if .Offline}}background-color: #eaeaea;{{else if gt .Rank 0}}background-color: #e6f3ff;{{end}}">
|
{{range .ItemList}}<div class="rowitem passive datarow" style="background-image:url({{.User.Avatar}});background-position:left;background-repeat:no-repeat;background-size:64px;padding-left:78px;{{if .Offline}}background-color:#eaeaea;{{else if gt .Rank 0}}background-color:#e6f3ff;{{end}}">
|
||||||
<span style="float: right;">
|
<span style="float:right;">
|
||||||
<span class="rank" style="font-size: 15px;">{{.RankString}}</span><br />
|
<span class="rank" style="font-size:15px;">{{.RankString}}</span><br />
|
||||||
<span class="joinedAt rowsmall">{{.JoinedAt}}</span>
|
<span class="joinedAt rowsmall">{{.JoinedAt}}</span>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
|
@ -32,4 +32,4 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</main>
|
</main>
|
||||||
{{template "footer.html" . }}
|
{{template "footer.html" . }}
|
|
@ -25,4 +25,4 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
{{template "footer.html" . }}
|
{{template "footer.html" . }}
|
|
@ -18,4 +18,4 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
{{template "footer.html" . }}
|
{{template "footer.html" . }}
|
|
@ -2,10 +2,11 @@
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_statistics_active_memory_head"}}</h1>
|
<h1>{{lang "panel_statistics_active_memory_head"}}</h1>
|
||||||
<select form="timeRangeForm" class="typeSelector to_right autoSubmitRedirect" name="mtype">
|
<select form="timeRangeForm" class="typeSelector to_right autoSubmitRedirect" name="mtype">
|
||||||
<option val="0"{{if eq .MemType 0}} selected{{end}}>{{lang "panel_statistics_memory_type_total"}}</option>
|
<option value="0"{{if eq .MemType 0}} selected{{end}}>{{lang "panel_statistics_memory_type_total"}}</option>
|
||||||
<option val="1"{{if eq .MemType 1}} selected{{end}}>{{lang "panel_statistics_memory_type_stack"}}</option>
|
<option value="1"{{if eq .MemType 1}} selected{{end}}>{{lang "panel_statistics_memory_type_stack"}}</option>
|
||||||
<option val="2"{{if eq .MemType 2}} selected{{end}}>{{lang "panel_statistics_memory_type_heap"}}</option>
|
<option value="2"{{if eq .MemType 2}} selected{{end}}>{{lang "panel_statistics_memory_type_heap"}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
<noscript><input form="timeRangeForm" type="submit" /></noscript>
|
||||||
{{template "panel_analytics_time_range_month.html" . }}
|
{{template "panel_analytics_time_range_month.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_statistics_referrers_head"}}</h1>
|
<h1>{{lang "panel_statistics_referrers_head"}}</h1>
|
||||||
<select form="timeRangeForm" class="spamSelector to_right autoSubmitRedirect" name="spam">
|
<select form="timeRangeForm" class="spamSelector to_right autoSubmitRedirect" name="spam">
|
||||||
<option val="0"{{if not .ShowSpam}} selected{{end}}>{{lang "panel_statistics_spam_hide"}}</option>
|
<option value="0"{{if not .ShowSpam}} selected{{end}}>{{lang "panel_statistics_spam_hide"}}</option>
|
||||||
<option val="1"{{if .ShowSpam}} selected{{end}}>{{lang "panel_statistics_spam_show"}}</option>
|
<option value="1"{{if .ShowSpam}} selected{{end}}>{{lang "panel_statistics_spam_show"}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
<noscript><input form="timeRangeForm" type="submit" /></noscript>
|
||||||
{{template "panel_analytics_time_range.html" . }}
|
{{template "panel_analytics_time_range.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<select form="timeRangeForm" class="timeRangeSelector to_right autoSubmitRedirect" name="timeRange">
|
<select form="timeRangeForm" class="timeRangeSelector to_right autoSubmitRedirect" name="timeRange">
|
||||||
<option val="one-year"{{if eq .TimeRange "one-year"}} selected{{end}}>{{lang "panel_statistics_time_range_one_year"}}</option>
|
<option value="one-year"{{if eq .TimeRange "one-year"}} selected{{end}}>{{lang "panel_statistics_time_range_one_year"}}</option>
|
||||||
<option val="three-months"{{if eq .TimeRange "three-months"}} selected{{end}}>{{lang "panel_statistics_time_range_three_months"}}</option>
|
<option value="three-months"{{if eq .TimeRange "three-months"}} selected{{end}}>{{lang "panel_statistics_time_range_three_months"}}</option>
|
||||||
<option val="one-month"{{if eq .TimeRange "one-month"}} selected{{end}}>{{lang "panel_statistics_time_range_one_month"}}</option>
|
<option value="one-month"{{if eq .TimeRange "one-month"}} selected{{end}}>{{lang "panel_statistics_time_range_one_month"}}</option>
|
||||||
<option val="one-week"{{if eq .TimeRange "one-week"}} selected{{end}}>{{lang "panel_statistics_time_range_one_week"}}</option>
|
<option value="one-week"{{if eq .TimeRange "one-week"}} selected{{end}}>{{lang "panel_statistics_time_range_one_week"}}</option>
|
||||||
<option val="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>{{lang "panel_statistics_time_range_two_days"}}</option>
|
<option value="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>{{lang "panel_statistics_time_range_two_days"}}</option>
|
||||||
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>{{lang "panel_statistics_time_range_one_day"}}</option>
|
<option value="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>{{lang "panel_statistics_time_range_one_day"}}</option>
|
||||||
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_twelve_hours"}}</option>
|
<option value="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_twelve_hours"}}</option>
|
||||||
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_six_hours"}}</option>
|
<option value="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_six_hours"}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
<noscript><input form="timeRangeForm" type="submit" /></noscript>
|
|
@ -1,8 +1,9 @@
|
||||||
<select form="timeRangeForm" class="timeRangeSelector to_right autoSubmitRedirect" name="timeRange">
|
<select form="timeRangeForm" class="timeRangeSelector to_right autoSubmitRedirect" name="timeRange">
|
||||||
<option val="one-month"{{if eq .TimeRange "one-month"}} selected{{end}}>{{lang "panel_statistics_time_range_one_month"}}</option>
|
<option value="one-month"{{if eq .TimeRange "one-month"}} selected{{end}}>{{lang "panel_statistics_time_range_one_month"}}</option>
|
||||||
<option val="one-week"{{if eq .TimeRange "one-week"}} selected{{end}}>{{lang "panel_statistics_time_range_one_week"}}</option>
|
<option value="one-week"{{if eq .TimeRange "one-week"}} selected{{end}}>{{lang "panel_statistics_time_range_one_week"}}</option>
|
||||||
<option val="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>{{lang "panel_statistics_time_range_two_days"}}</option>
|
<option value="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>{{lang "panel_statistics_time_range_two_days"}}</option>
|
||||||
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>{{lang "panel_statistics_time_range_one_day"}}</option>
|
<option value="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>{{lang "panel_statistics_time_range_one_day"}}</option>
|
||||||
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_twelve_hours"}}</option>
|
<option value="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_twelve_hours"}}</option>
|
||||||
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_six_hours"}}</option>
|
<option value="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_six_hours"}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
<noscript><input form="timeRangeForm" type="submit" /></noscript>
|
|
@ -7,7 +7,7 @@
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_setting_value"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_setting_value"}}</a></div>
|
||||||
<div class="formitem">
|
<div class="formitem">
|
||||||
<select name="setting-value">
|
<select name="value">
|
||||||
{{range .ItemList}}<option{{if .Selected}} selected{{end}} value="{{.Value}}">{{.Label}}</option>{{end}}
|
{{range .ItemList}}<option{{if .Selected}} selected{{end}} value="{{.Value}}">{{.Label}}</option>{{end}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,19 +16,19 @@
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_setting_value"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_setting_value"}}</a></div>
|
||||||
<div class="formitem">
|
<div class="formitem">
|
||||||
<select name="setting-value">
|
<select name="value">
|
||||||
<option{{if eq .Setting.Content "1"}} selected{{end}} value="1">{{lang "option_yes"}}</option>
|
<option{{if eq .Setting.Content "1"}} selected{{end}} value=1>{{lang "option_yes"}}</option>
|
||||||
<option{{if eq .Setting.Content "0"}} selected{{end}} value="0">{{lang "option_no"}}</option>
|
<option{{if eq .Setting.Content "0"}} selected{{end}} value=0>{{lang "option_no"}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{else if eq .Setting.Type "textarea"}}
|
{{else if eq .Setting.Type "textarea"}}
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem"><textarea name="setting-value">{{.Setting.Content}}</textarea></div>
|
<div class="formitem"><textarea name="value">{{.Setting.Content}}</textarea></div>
|
||||||
</div>
|
</div>
|
||||||
{{else}}<div class="formrow">
|
{{else}}<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_setting_value"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_setting_value"}}</a></div>
|
||||||
<div class="formitem"><input name="setting-value" type="text" value="{{.Setting.Content}}" /></div>
|
<div class="formitem"><input name="value" type="text" value="{{.Setting.Content}}"/></div>
|
||||||
</div>{{end}}
|
</div>{{end}}
|
||||||
<div class="formrow form_button_row">
|
<div class="formrow form_button_row">
|
||||||
<div class="formitem"><button name="panel-button" class="formbutton">{{lang "panel_setting_update_button"}}</button></div>
|
<div class="formitem"><button name="panel-button" class="formbutton">{{lang "panel_setting_update_button"}}</button></div>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
{{if .Poll.ID}}{{template "topic_poll.html" . }}{{end}}
|
{{if .Poll.ID}}{{template "topic_poll.html" . }}{{end}}
|
||||||
|
|
||||||
<article {{scope "opening_post"}} itemscope itemtype="http://schema.org/CreativeWork" class="rowblock post_container top_post" aria-label="{{lang "topic.opening_post_aria"}}">
|
<article {{scope "opening_post"}} itemscope itemtype="http://schema.org/CreativeWork" class="rowblock post_container top_post" aria-label="{{lang "topic.opening_post_aria"}}">
|
||||||
<div class="rowitem passive editable_parent post_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}), url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat,repeat-y;">
|
<div class="rowitem passive editable_parent post_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}),url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat,repeat-y;">
|
||||||
<div class="hide_on_edit topic_content user_content" itemprop="text">{{.Topic.ContentHTML}}</div>
|
<div class="hide_on_edit topic_content user_content" itemprop="text">{{.Topic.ContentHTML}}</div>
|
||||||
{{if .CurrentUser.Loggedin}}<textarea name="topic_content" class="show_on_edit topic_content_input edit_source">{{.Topic.Content}}</textarea>{{end}}
|
{{if .CurrentUser.Loggedin}}<textarea name="topic_content" class="show_on_edit topic_content_input edit_source">{{.Topic.Content}}</textarea>{{end}}
|
||||||
|
|
||||||
|
|
|
@ -121,5 +121,4 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{{template "footer.html" . }}
|
{{template "footer.html" . }}
|
|
@ -1,9 +1,13 @@
|
||||||
<div class="rowblock topic_reply_container">
|
<div class="rowblock topic_reply_container">
|
||||||
<div class="userinfo" aria-label="{{lang "topic.your_information"}}">
|
<div class="userinfo" aria-label="{{lang "topic.your_information"}}">
|
||||||
<div class="avatar_item" style="background-image:url({{.CurrentUser.Avatar}}),url(/s/white-dot.jpg);background-position:0px -10px;"> </div>
|
<div class="avatar_item" style="background-image:url({{.CurrentUser.Avatar}}),url(/s/white-dot.jpg);"> </div>
|
||||||
<div class="user_meta">
|
<div class="user_meta">
|
||||||
<a href="{{.CurrentUser.Link}}" class="the_name" rel="author">{{.CurrentUser.Name}}</a>
|
<a href="{{.CurrentUser.Link}}" class="the_name" rel="author">{{.CurrentUser.Name}}</a>
|
||||||
{{if .CurrentUser.Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.CurrentUser.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">{{level .CurrentUser.Level}}</div><div class="tag_post"></div></div>{{end}}
|
<div class="tag_block">
|
||||||
|
<div class="tag_pre"></div>
|
||||||
|
{{if .CurrentUser.Tag}}<div class="post_tag">{{.CurrentUser.Tag}}</div>{{else}}<div class="post_tag post_level">{{level .CurrentUser.Level}}</div>{{end}}
|
||||||
|
<div class="tag_post"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rowblock topic_reply_form quick_create_form" aria-label="{{lang "topic.reply_aria"}}">
|
<div class="rowblock topic_reply_form quick_create_form" aria-label="{{lang "topic.reply_aria"}}">
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
<div class="userinfo" aria-label="{{lang "topic.userinfo_aria"}}">
|
<div class="userinfo" aria-label="{{lang "topic.userinfo_aria"}}">
|
||||||
<div class="avatar_item" style="background-image:url({{.Avatar}}), url(/s/white-dot.jpg);background-position:0px -10px;"> </div>
|
<div class="avatar_item" style="background-image:url({{.Avatar}}),url(/s/white-dot.jpg);"> </div>
|
||||||
<div class="user_meta">
|
<div class="user_meta">
|
||||||
<a href="{{.UserLink}}" class="the_name" rel="author">{{.CreatedByName}}</a>
|
<a href="{{.UserLink}}" class="the_name" rel="author">{{.CreatedByName}}</a>
|
||||||
{{if .Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">{{level .Level}}</div><div class="tag_post"></div></div>{{end}}
|
<div class="tag_block">
|
||||||
|
<div class="tag_pre"></div>
|
||||||
|
{{if .Tag}}<div class="post_tag">{{.Tag}}</div>{{else}}<div class="post_tag post_level">{{level .Level}}</div>{{end}}
|
||||||
|
<div class="tag_post"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -1,5 +1,5 @@
|
||||||
<article class="rowblock post_container poll" aria-level="{{lang "topic.poll_aria"}}">
|
<article class="rowblock post_container poll" aria-level="{{lang "topic.poll_aria"}}">
|
||||||
<div class="rowitem passive editable_parent post_item poll_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}), url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat,repeat-y;">
|
<div class="rowitem passive editable_parent post_item poll_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}),url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat,repeat-y;">
|
||||||
<div class="topic_content user_content">
|
<div class="topic_content user_content">
|
||||||
{{range .Poll.QuickOptions}}
|
{{range .Poll.QuickOptions}}
|
||||||
<div class="poll_option">
|
<div class="poll_option">
|
||||||
|
|
|
@ -1059,6 +1059,7 @@ blockquote:first-child {
|
||||||
width: 84px;
|
width: 84px;
|
||||||
height: 84px;
|
height: 84px;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
|
background-position: 0px -10px;
|
||||||
background-size: 120px;
|
background-size: 120px;
|
||||||
}
|
}
|
||||||
.the_name, .userinfo .tag_block {
|
.the_name, .userinfo .tag_block {
|
||||||
|
|
|
@ -837,6 +837,7 @@ blockquote:first-child {
|
||||||
border-radius: 36px;
|
border-radius: 36px;
|
||||||
height: 58px;
|
height: 58px;
|
||||||
width: 58px;
|
width: 58px;
|
||||||
|
background-position: 0px -10px;
|
||||||
background-size: 78px;
|
background-size: 78px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
|
Loading…
Reference in New Issue