Added a custom auto-link parser rather than using a regex.

Added the Tempra Cursive theme. A fork of Tempra Simple which is less boxy and uses the cursive font.
Improved the theme manager. Primary themes and variant themes (themes based upon another) are now seperate.
plugin_bbcode has been modified to use the URL parsing facilities of the core rather than implementing them itself.
git:// and ftp:// links are now supported by plugin_bbcode.
Added the simple quote BBCode.
Fixed a bug in route_like_topic where the no row error type isn't handled properly.
Moved the rowhead class onto the right element in the topic template.
Removed a couple of linebreaks in the topic template in favour of pure CSS.
Converted some inline CSS in the topic template into new CSS classes.

alerts.png contains some alert types for features which haven't been implemented yet, this is mainly to test if the alert system would work under the presence of those alert types. Think of this as my plans for the future.
This commit is contained in:
Azareal 2017-03-07 07:22:29 +00:00
parent 905a51d294
commit ea63768a8e
21 changed files with 897 additions and 87 deletions

View File

@ -9,9 +9,7 @@ More moderation features. E.g. Move, Approval Queue (Posts made by users in cert
Add a simple anti-spam measure. I have quite a few ideas in mind, but it'll take a while to implement the more advanced ones, so I'd like to put off some of those to a later date and focus on the basics. E.g. CAPTCHAs, hidden fields, etc. Add a simple anti-spam measure. I have quite a few ideas in mind, but it'll take a while to implement the more advanced ones, so I'd like to put off some of those to a later date and focus on the basics. E.g. CAPTCHAs, hidden fields, etc.
Add a modern alert system. Add more granular permissions management to the Forum Manager.
Add per-forum permissions to finish up the foundations of the permissions system.
Add a *better* plugin system. E.g. Allow for plugins written in Javascript and ones written in Go. Also, we need to add many, many, many more plugin hooks. Add a *better* plugin system. E.g. Allow for plugins written in Javascript and ones written in Go. Also, we need to add many, many, many more plugin hooks.

BIN
images/alerts.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
images/tempra-cursive.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB

View File

@ -1410,15 +1410,21 @@ func route_panel_themes(w http.ResponseWriter, r *http.Request){
return return
} }
var themeList []interface{} var pThemeList []Theme
var vThemeList []Theme
for _, theme := range themes { for _, theme := range themes {
if theme.HideFromThemes { if theme.HideFromThemes {
continue continue
} }
themeList = append(themeList,theme) if theme.ForkOf == "" {
pThemeList = append(pThemeList,theme)
} else {
vThemeList = append(vThemeList,theme)
} }
pi := Page{"Theme Manager",user,noticeList,themeList,nil} }
pi := ThemesPage{"Theme Manager",user,noticeList,pThemeList,vThemeList,nil}
err := templates.ExecuteTemplate(w,"panel-themes.html",pi) err := templates.ExecuteTemplate(w,"panel-themes.html",pi)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

241
pages.go
View File

@ -1,4 +1,6 @@
package main package main
//import "fmt"
import "bytes"
import "strings" import "strings"
import "regexp" import "regexp"
@ -73,6 +75,16 @@ type CreateTopicPage struct
ExtData interface{} ExtData interface{}
} }
type ThemesPage struct
{
Title string
CurrentUser User
NoticeList []string
PrimaryThemes []Theme
VariantThemes []Theme
ExtData interface{}
}
type PageSimple struct type PageSimple struct
{ {
Title string Title string
@ -85,6 +97,12 @@ type AreYouSure struct
Message string Message string
} }
var space_gap []byte = []byte(" ")
var http_prot_b []byte = []byte("http://")
var invalid_url []byte = []byte("<span style='color: red;'>[Invalid URL]</span>")
var url_open []byte = []byte("<a href='")
var url_open2 []byte = []byte("'>")
var url_close []byte = []byte("</a>")
var urlpattern string = `(?s)([ {1}])((http|https|ftp|mailto)*)(:{??)\/\/([\.a-zA-Z\/]+)([ {1}])` var urlpattern string = `(?s)([ {1}])((http|https|ftp|mailto)*)(:{??)\/\/([\.a-zA-Z\/]+)([ {1}])`
var url_reg *regexp.Regexp var url_reg *regexp.Regexp
@ -144,6 +162,89 @@ func preparse_message(msg string) string {
} }
func parse_message(msg string) string { func parse_message(msg string) string {
msg = strings.Replace(msg,":)","😀",-1)
msg = strings.Replace(msg,":D","😃",-1)
msg = strings.Replace(msg,":P","😛",-1)
//msg = url_reg.ReplaceAllString(msg,"<a href=\"$2$3//$4\" rel=\"nofollow\">$2$3//$4</a>")
// Search for URLs in the messages...
var msgbytes = []byte(msg)
outbytes := make([]byte, len(msgbytes))
msgbytes = append(msgbytes,space_gap...)
//fmt.Println(`"`+string(msgbytes)+`"`)
lastItem := 0
i := 0
for ; len(msgbytes) > (i + 1); i++ {
if i==0 || msgbytes[i] == 10 || (msgbytes[i] == ' ' && msgbytes[i + 1] != ' ') {
i++
if msgbytes[i] != 'h' && msgbytes[i] != 'f' && msgbytes[i] != 'g' && msgbytes[i + 1] != 't' {
continue
}
if msgbytes[i + 2] == 't' && msgbytes[i + 3] == 'p' {
if msgbytes[i + 4] == 's' && msgbytes[i + 5] == ':' && msgbytes[i + 6] == '/' && msgbytes[i + 7] == '/' {
// Do nothing
} else if msgbytes[i + 4] == ':' && msgbytes[i + 5] == '/' && msgbytes[i + 6] == '/' {
// Do nothing
} else {
continue
}
} else if msgbytes[i + 2] == 'p' && msgbytes[i + 3] == ':' && msgbytes[i + 4] == '/' && msgbytes[i + 5] == '/' {
// Do nothing
} else if msgbytes[i + 1] == 'i' && msgbytes[i + 2] == 't' && msgbytes[i + 3] == ':' && msgbytes[i + 4] == '/' && msgbytes[i + 5] == '/' {
// Do nothing
} else {
continue
}
outbytes = append(outbytes,msgbytes[lastItem:i]...)
url_len := partial_url_bytes_len(msgbytes[i:])
if msgbytes[i + url_len] != ' ' && msgbytes[i + url_len] != 10 {
outbytes = append(outbytes,invalid_url...)
i += url_len
continue
}
//fmt.Println("Parsed URL:")
//fmt.Println("`"+string(msgbytes[i:i + url_len])+"`")
//fmt.Println("-----")
outbytes = append(outbytes, url_open...)
outbytes = append(outbytes, msgbytes[i:i + url_len]...)
outbytes = append(outbytes, url_open2...)
outbytes = append(outbytes, msgbytes[i:i + url_len]...)
outbytes = append(outbytes, url_close...)
i += url_len
lastItem = i
}
}
if lastItem != i && len(outbytes) != 0 {
//fmt.Println("lastItem:")
//fmt.Println(msgbytes[lastItem])
//fmt.Println("lastItem index:")
//fmt.Println(lastItem)
//fmt.Println("i:")
//fmt.Println(i)
//fmt.Println("lastItem to end:")
//fmt.Println(msgbytes[lastItem:])
//fmt.Println("-----")
calclen := len(msgbytes) - 10
if calclen <= lastItem {
calclen = lastItem
}
outbytes = append(outbytes, msgbytes[lastItem:calclen]...)
msg = string(outbytes)
}
//fmt.Println(`"`+string(outbytes)+`"`)
//fmt.Println(`"`+msg+`"`)
msg = strings.Replace(msg,"\n","<br>",-1)
if hooks["parse_assign"] != nil {
out := run_hook("parse_assign", msg)
msg = out.(string)
}
return msg
}
func regex_parse_message(msg string) string {
msg = strings.Replace(msg,":)","😀",-1) msg = strings.Replace(msg,":)","😀",-1)
msg = strings.Replace(msg,":D","😃",-1) msg = strings.Replace(msg,":D","😃",-1)
msg = strings.Replace(msg,":P","😛",-1) msg = strings.Replace(msg,":P","😛",-1)
@ -155,3 +256,143 @@ func parse_message(msg string) string {
} }
return msg return msg
} }
// 6, 7, 8, 6, 7
// ftp://, http://, https:// git://, mailto: (not a URL, just here for length comparison purposes)
func validate_url_bytes(data []byte) bool {
datalen := len(data)
i := 0
if datalen >= 6 {
if bytes.Equal(data[0:6],[]byte("ftp://")) || bytes.Equal(data[0:6],[]byte("git://")) {
i = 6
} else if datalen >= 7 && bytes.Equal(data[0:7],http_prot_b) {
i = 7
} else if datalen >= 8 && bytes.Equal(data[0:8],[]byte("https://")) {
i = 8
}
}
for ;datalen > i; i++ {
if data[i] != '\\' && data[i] != '_' && !(data[i] > 44 && data[i] < 58) && !(data[i] > 64 && data[i] < 91) && !(data[i] > 96 && data[i] < 123) {
return false
}
}
return true
}
func validated_url_bytes(data []byte) (url []byte) {
datalen := len(data)
i := 0
if datalen >= 6 {
if bytes.Equal(data[0:6],[]byte("ftp://")) || bytes.Equal(data[0:6],[]byte("git://")) {
i = 6
} else if datalen >= 7 && bytes.Equal(data[0:7],http_prot_b) {
i = 7
} else if datalen >= 8 && bytes.Equal(data[0:8],[]byte("https://")) {
i = 8
}
}
for ;datalen > i; i++ {
if data[i] != '\\' && data[i] != '_' && !(data[i] > 44 && data[i] < 58) && !(data[i] > 64 && data[i] < 91) && !(data[i] > 96 && data[i] < 123) {
return invalid_url
}
}
url = append(url, data...)
return url
}
func partial_url_bytes(data []byte) (url []byte) {
datalen := len(data)
i := 0
end := datalen - 1
if datalen >= 6 {
if bytes.Equal(data[0:6],[]byte("ftp://")) || bytes.Equal(data[0:6],[]byte("git://")) {
i = 6
} else if datalen >= 7 && bytes.Equal(data[0:7],http_prot_b) {
i = 7
} else if datalen >= 8 && bytes.Equal(data[0:8],[]byte("https://")) {
i = 8
}
}
for ;end >= i; i++ {
if data[i] != '\\' && data[i] != '_' && !(data[i] > 44 && data[i] < 58) && !(data[i] > 64 && data[i] < 91) && !(data[i] > 96 && data[i] < 123) {
end = i
}
}
url = append(url, data[0:end]...)
return url
}
func partial_url_bytes_len(data []byte) int {
datalen := len(data)
i := 0
if datalen >= 6 {
//fmt.Println(data[0:5])
//fmt.Println(string(data[0:5]))
if bytes.Equal(data[0:6],[]byte("ftp://")) || bytes.Equal(data[0:6],[]byte("git://")) {
i = 6
} else if datalen >= 7 && bytes.Equal(data[0:7],http_prot_b) {
i = 7
//fmt.Println("http")
} else if datalen >= 8 && bytes.Equal(data[0:8],[]byte("https://")) {
i = 8
} else {
//fmt.Println("no protocol")
}
}
for ;datalen > i; i++ {
if data[i] != '\\' && data[i] != '_' && !(data[i] > 44 && data[i] < 58) && !(data[i] > 64 && data[i] < 91) && !(data[i] > 96 && data[i] < 123) {
//fmt.Println("Trimmed Length")
//fmt.Println(i)
//fmt.Println("Full Length")
//fmt.Println(i)
//fmt.Println("Data Length:")
//fmt.Println(datalen)
//fmt.Println("Bad Character:")
//fmt.Println(data[i])
return i
}
}
//fmt.Println("Data Length:")
//fmt.Println(datalen)
return datalen
}
func parse_media_bytes(data []byte) (protocol []byte, url []byte) {
datalen := len(data)
i := 0
if datalen >= 6 {
if bytes.Equal(data[0:6],[]byte("ftp://")) || bytes.Equal(data[0:6],[]byte("git://")) {
i = 6
protocol = data[0:2]
} else if datalen >= 7 && bytes.Equal(data[0:7],http_prot_b) {
i = 7
protocol = []byte("http")
} else if datalen >= 8 && bytes.Equal(data[0:8],[]byte("https://")) {
i = 8
protocol = []byte("https")
}
}
for ;datalen > i; i++ {
if data[i] != '\\' && data[i] != '_' && !(data[i] > 44 && data[i] < 58) && !(data[i] > 64 && data[i] < 91) && !(data[i] > 96 && data[i] < 123) {
return []byte(""), invalid_url
}
}
if len(protocol) == 0 {
protocol = []byte("http")
}
return protocol, data[i:]
}

View File

@ -9,13 +9,8 @@ import "time"
import "math/rand" import "math/rand"
var random *rand.Rand var random *rand.Rand
var bbcode_invalid_url []byte
var bbcode_invalid_number []byte var bbcode_invalid_number []byte
var bbcode_missing_tag []byte var bbcode_missing_tag []byte
var bbcode_url_open []byte
var bbcode_url_open2 []byte
var bbcode_url_close []byte
var bbcode_space_gap []byte
var bbcode_bold *regexp.Regexp var bbcode_bold *regexp.Regexp
var bbcode_italic *regexp.Regexp var bbcode_italic *regexp.Regexp
@ -23,6 +18,7 @@ var bbcode_underline *regexp.Regexp
var bbcode_strikethrough *regexp.Regexp var bbcode_strikethrough *regexp.Regexp
var bbcode_url *regexp.Regexp var bbcode_url *regexp.Regexp
var bbcode_url_label *regexp.Regexp var bbcode_url_label *regexp.Regexp
var bbcode_quotes *regexp.Regexp
func init() { func init() {
plugins["bbcode"] = NewPlugin("bbcode","BBCode","Azareal","http://github.com/Azareal","","","",init_bbcode,nil,deactivate_bbcode) plugins["bbcode"] = NewPlugin("bbcode","BBCode","Azareal","http://github.com/Azareal","","","",init_bbcode,nil,deactivate_bbcode)
@ -32,13 +28,8 @@ func init_bbcode() {
//plugins["bbcode"].AddHook("parse_assign", bbcode_parse_without_code) //plugins["bbcode"].AddHook("parse_assign", bbcode_parse_without_code)
plugins["bbcode"].AddHook("parse_assign", bbcode_full_parse) plugins["bbcode"].AddHook("parse_assign", bbcode_full_parse)
bbcode_invalid_url = []byte("<span style='color: red;'>[Invalid URL]</span>")
bbcode_invalid_number = []byte("<span style='color: red;'>[Invalid Number]</span>") bbcode_invalid_number = []byte("<span style='color: red;'>[Invalid Number]</span>")
bbcode_missing_tag = []byte("<span style='color: red;'>[Missing Tag]</span>") bbcode_missing_tag = []byte("<span style='color: red;'>[Missing Tag]</span>")
bbcode_url_open = []byte("<a href='")
bbcode_url_open2 = []byte("'>")
bbcode_url_close = []byte("</a>")
bbcode_space_gap = []byte(" ")
bbcode_bold = regexp.MustCompile(`(?s)\[b\](.*)\[/b\]`) bbcode_bold = regexp.MustCompile(`(?s)\[b\](.*)\[/b\]`)
bbcode_italic = regexp.MustCompile(`(?s)\[i\](.*)\[/i\]`) bbcode_italic = regexp.MustCompile(`(?s)\[i\](.*)\[/i\]`)
@ -47,6 +38,7 @@ func init_bbcode() {
urlpattern := `(http|https|ftp|mailto*)(:??)\/\/([\.a-zA-Z\/]+)` urlpattern := `(http|https|ftp|mailto*)(:??)\/\/([\.a-zA-Z\/]+)`
bbcode_url = regexp.MustCompile(`\[url\]` + urlpattern + `\[/url\]`) bbcode_url = regexp.MustCompile(`\[url\]` + urlpattern + `\[/url\]`)
bbcode_url_label = regexp.MustCompile(`(?s)\[url=` + urlpattern + `\](.*)\[/url\]`) bbcode_url_label = regexp.MustCompile(`(?s)\[url=` + urlpattern + `\](.*)\[/url\]`)
bbcode_quotes = regexp.MustCompile(`\[quote\](.*)\[/quote\]`)
random = rand.New(rand.NewSource(time.Now().UnixNano())) random = rand.New(rand.NewSource(time.Now().UnixNano()))
} }
@ -64,6 +56,7 @@ func bbcode_regex_parse(data interface{}) interface{} {
msg = bbcode_strikethrough.ReplaceAllString(msg,"<s>$1</s>") msg = bbcode_strikethrough.ReplaceAllString(msg,"<s>$1</s>")
msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>") msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>")
msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>") msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>")
msg = bbcode_quotes.ReplaceAllString(msg,"<div class=\"postQuote\">$1</div>")
return msg return msg
} }
@ -177,6 +170,7 @@ func bbcode_parse_without_code(data interface{}) interface{} {
if complex_bbc { if complex_bbc {
msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>") msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>")
msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>") msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>")
msg = bbcode_quotes.ReplaceAllString(msg,"<div class=\"postQuote\">$1</div>")
} }
return string(msgbytes) return string(msgbytes)
} }
@ -184,6 +178,9 @@ func bbcode_parse_without_code(data interface{}) interface{} {
// Does every type of BBCode // Does every type of BBCode
func bbcode_full_parse(data interface{}) interface{} { func bbcode_full_parse(data interface{}) interface{} {
msg := data.(string) msg := data.(string)
//fmt.Println("BBCode PrePre String:")
//fmt.Println("`"+msg+"`")
//fmt.Println("----")
msgbytes := []byte(msg) msgbytes := []byte(msg)
has_u := false has_u := false
has_b := false has_b := false
@ -191,7 +188,10 @@ func bbcode_full_parse(data interface{}) interface{} {
has_s := false has_s := false
has_c := false has_c := false
complex_bbc := false complex_bbc := false
msgbytes = append(msgbytes,bbcode_space_gap...) msgbytes = append(msgbytes,space_gap...)
//fmt.Println("BBCode Simple Pre:")
//fmt.Println("`"+string(msgbytes)+"`")
//fmt.Println("----")
for i := 0; i < len(msgbytes); i++ { for i := 0; i < len(msgbytes); i++ {
if msgbytes[i] == '[' { if msgbytes[i] == '[' {
if msgbytes[i + 2] != ']' { if msgbytes[i + 2] != ']' {
@ -275,59 +275,36 @@ func bbcode_full_parse(data interface{}) interface{} {
var start int var start int
var lastTag int var lastTag int
outbytes := make([]byte, len(msgbytes)) outbytes := make([]byte, len(msgbytes))
//fmt.Println(string(msgbytes)) //fmt.Println("BBCode Pre:")
//fmt.Println("`"+string(msgbytes)+"`")
//fmt.Println("----")
for ; i < len(msgbytes); i++ { for ; i < len(msgbytes); i++ {
MainLoop: MainLoop:
if msgbytes[i] == '[' { if msgbytes[i] == '[' {
OuterComplex: OuterComplex:
if msgbytes[i + 1] == 'u' { if msgbytes[i + 1] == 'u' {
if msgbytes[i+2] == 'r' && msgbytes[i+3] == 'l' && msgbytes[i+4] == ']' { if msgbytes[i+2] == 'r' && msgbytes[i+3] == 'l' && msgbytes[i+4] == ']' {
outbytes = append(outbytes, msgbytes[lastTag:i]...)
start = i + 5 start = i + 5
outbytes = append(outbytes, msgbytes[lastTag:i]...)
i = start i = start
if msgbytes[i] == 'h' { i += partial_url_bytes_len(msgbytes[start:])
if msgbytes[i+1] == 't' && msgbytes[i+2] == 't' && msgbytes[i+3] == 'p' {
if bytes.Equal(msgbytes[i + 4:i + 7],[]byte("s://")) {
i += 7
} else if msgbytes[i+4] == ':' && msgbytes[i+5] == '/' && msgbytes[i+6] == '/' {
i += 6
} else {
outbytes = append(outbytes, bbcode_invalid_url...)
continue
}
}
} else if msgbytes[i] == 'f' {
if bytes.Equal(msgbytes[i+1:i+5],[]byte("tp://")) {
i += 5
}
}
for ;; i++ { //fmt.Println("Partial Bytes:")
if len(msgbytes) < (i + 10) { //fmt.Println(string(msgbytes[start:]))
//fmt.Println(msglen) //fmt.Println("-----")
//fmt.Println(i+6) if !bytes.Equal(msgbytes[i:i+6],[]byte("[/url]")) {
outbytes = append(outbytes, bbcode_missing_tag...) //fmt.Println("Invalid Bytes:")
goto OuterComplex //fmt.Println(string(msgbytes[i:i+6]))
} else if msgbytes[i] == '[' { //fmt.Println("-----")
if !bytes.Equal(msgbytes[i+1:i+6],[]byte("/url]")) { outbytes = append(outbytes, invalid_url...)
//log.Print("Not the URL closing tag!")
//fmt.Println(msgbytes[i + 1:i + 6])
outbytes = append(outbytes, bbcode_missing_tag...)
goto OuterComplex
}
break
} else if msgbytes[i] != '\\' && msgbytes[i] != '_' && !(msgbytes[i] > 44 && msgbytes[i] < 58) && !(msgbytes[i] > 64 && msgbytes[i] < 91) && !(msgbytes[i] > 96 && msgbytes[i] < 123) {
outbytes = append(outbytes, bbcode_invalid_url...)
//log.Print("Weird character")
//fmt.Println(msgbytes[i])
goto MainLoop goto MainLoop
} }
}
outbytes = append(outbytes, bbcode_url_open...) outbytes = append(outbytes, url_open...)
outbytes = append(outbytes, msgbytes[start:i]...) outbytes = append(outbytes, msgbytes[start:i]...)
outbytes = append(outbytes, bbcode_url_open2...) outbytes = append(outbytes, url_open2...)
outbytes = append(outbytes, msgbytes[start:i]...) outbytes = append(outbytes, msgbytes[start:i]...)
outbytes = append(outbytes, bbcode_url_close...) outbytes = append(outbytes, url_close...)
i += 6 i += 6
lastTag = i lastTag = i
} }
@ -367,15 +344,25 @@ func bbcode_full_parse(data interface{}) interface{} {
//fmt.Println(string(outbytes)) //fmt.Println(string(outbytes))
if lastTag != i { if lastTag != i {
outbytes = append(outbytes, msgbytes[lastTag:]...) outbytes = append(outbytes, msgbytes[lastTag:]...)
} //fmt.Println("Outbytes:")
if len(outbytes) != 0 { //fmt.Println(`"`+string(outbytes)+`"`)
return string(outbytes[0:len(msgbytes) - 10]) //fmt.Println("----")
} }
if len(outbytes) != 0 {
//fmt.Println("BBCode Post:")
//fmt.Println(`"`+string(outbytes[0:len(outbytes) - 10])+`"`)
//fmt.Println("----")
msg = string(outbytes[0:len(outbytes) - 10])
} else {
msg = string(msgbytes[0:len(msgbytes) - 10]) msg = string(msgbytes[0:len(msgbytes) - 10])
}
//msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>") //msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>")
msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>") msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>")
msg = bbcode_quotes.ReplaceAllString(msg,"<div class=\"postQuote\">$1</div>")
// Convert [code] into class="codequotes" // Convert [code] into class="codequotes"
//fmt.Println("guuuaaaa")
} else { } else {
msg = string(msgbytes[0:len(msgbytes) - 10]) msg = string(msgbytes[0:len(msgbytes) - 10])
} }

View File

@ -780,7 +780,7 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
} }
_, err = users.CascadeGet(createdBy) _, err = users.CascadeGet(createdBy)
if err != nil && err != sql.ErrNoRows { if err != nil && err == sql.ErrNoRows {
LocalError("The target user doesn't exist",w,r,user) LocalError("The target user doesn't exist",w,r,user)
return return
} else if err != nil { } else if err != nil {

View File

@ -67,7 +67,7 @@ var topic_8 []byte = []byte(`
<div class="rowblock topic_block"> <div class="rowblock topic_block">
<form action='/topic/edit/submit/`) <form action='/topic/edit/submit/`)
var topic_9 []byte = []byte(`' method="post"> var topic_9 []byte = []byte(`' method="post">
<div class="rowitem topic_item"`) <div class="rowitem rowhead topic_item"`)
var topic_10 []byte = []byte(` style="background-color:#FFFFEA;"`) var topic_10 []byte = []byte(` style="background-color:#FFFFEA;"`)
var topic_11 []byte = []byte(` style="background-color:#eaeaea;"`) var topic_11 []byte = []byte(` style="background-color:#eaeaea;"`)
var topic_12 []byte = []byte(`> var topic_12 []byte = []byte(`>
@ -100,7 +100,7 @@ var topic_24 []byte = []byte(`">
<p class="hide_on_edit topic_content user_content" style="margin:0;padding:0;">`) <p class="hide_on_edit topic_content user_content" style="margin:0;padding:0;">`)
var topic_25 []byte = []byte(`</p> var topic_25 []byte = []byte(`</p>
<textarea name="topic_content" class="show_on_edit topic_content_input">`) <textarea name="topic_content" class="show_on_edit topic_content_input">`)
var topic_26 []byte = []byte(`</textarea><br /><br /> var topic_26 []byte = []byte(`</textarea>
<a href="/user/`) <a href="/user/`)
var topic_27 []byte = []byte(`" class="username real_username">`) var topic_27 []byte = []byte(`" class="username real_username">`)
var topic_28 []byte = []byte(`</a>&nbsp; var topic_28 []byte = []byte(`</a>&nbsp;
@ -126,21 +126,21 @@ var topic_44 []byte = []byte(`<a class="username hide_on_micro" style="float: ri
var topic_45 []byte = []byte(`</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;margin-left:5px;" title="Like Count">😀</a>`) var topic_45 []byte = []byte(`</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;margin-left:5px;" title="Like Count">😀</a>`)
var topic_46 []byte = []byte(`<a class="username hide_on_micro" style="float:right;color:#505050;font-size:16px;">`) var topic_46 []byte = []byte(`<a class="username hide_on_micro" style="float:right;color:#505050;font-size:16px;">`)
var topic_47 []byte = []byte(`</a>`) var topic_47 []byte = []byte(`</a>`)
var topic_48 []byte = []byte(`<a class="username hide_on_micro" style="float: right;color:#505050;border-left:none;padding-left:5px;padding-right:5px;font-size:17px;">`) var topic_48 []byte = []byte(`<a class="username hide_on_micro level">`)
var topic_49 []byte = []byte(`</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;" title="Level">👑</a>`) var topic_49 []byte = []byte(`</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;" title="Level">👑</a>`)
var topic_50 []byte = []byte(` var topic_50 []byte = []byte(`
</div> </div>
</div><br /> </div><br />
<div class="rowblock post_container" style="overflow: hidden;">`) <div class="rowblock post_container" style="overflow: hidden;">`)
var topic_51 []byte = []byte(` var topic_51 []byte = []byte(`
<div class="rowitem rowhead passive deletable_block editable_parent post_item" style="`) <div class="rowitem passive deletable_block editable_parent post_item" style="`)
var topic_52 []byte = []byte(`background-image:url(`) var topic_52 []byte = []byte(`background-image:url(`)
var topic_53 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `) var topic_53 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `)
var topic_54 []byte = []byte(`-1`) var topic_54 []byte = []byte(`-1`)
var topic_55 []byte = []byte(`0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;`) var topic_55 []byte = []byte(`0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;`)
var topic_56 []byte = []byte(`"> var topic_56 []byte = []byte(`">
<p class="editable_block user_content" style="margin: 0;padding: 0;">`) <p class="editable_block user_content" style="margin: 0;padding: 0;">`)
var topic_57 []byte = []byte(`</p><br /><br /> var topic_57 []byte = []byte(`</p>
<a href="/user/`) <a href="/user/`)
var topic_58 []byte = []byte(`" class="username real_username">`) var topic_58 []byte = []byte(`" class="username real_username">`)
var topic_59 []byte = []byte(`</a>&nbsp; var topic_59 []byte = []byte(`</a>&nbsp;
@ -162,7 +162,7 @@ var topic_71 []byte = []byte(`<a class="username hide_on_micro" style="float: ri
var topic_72 []byte = []byte(`</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;margin-left:5px;" title="Like Count">😀</a>`) var topic_72 []byte = []byte(`</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;margin-left:5px;" title="Like Count">😀</a>`)
var topic_73 []byte = []byte(`<a class="username hide_on_micro" style="float: right;color:#505050;font-size:16px;">`) var topic_73 []byte = []byte(`<a class="username hide_on_micro" style="float: right;color:#505050;font-size:16px;">`)
var topic_74 []byte = []byte(`</a>`) var topic_74 []byte = []byte(`</a>`)
var topic_75 []byte = []byte(`<a class="username hide_on_micro" style="float: right;color:#505050;border-left:none;padding-left:5px;padding-right:5px;font-size:17px;">`) var topic_75 []byte = []byte(`<a class="username hide_on_micro level">`)
var topic_76 []byte = []byte(`</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;" title="Level">👑`) var topic_76 []byte = []byte(`</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;" title="Level">👑`)
var topic_77 []byte = []byte(`</a> var topic_77 []byte = []byte(`</a>
</div> </div>

View File

@ -2,10 +2,28 @@
{{template "panel-menu.html" . }} {{template "panel-menu.html" . }}
<style type="text/css">.rowitem::after {content:"";display:block;clear:both;}</style> <style type="text/css">.rowitem::after {content:"";display:block;clear:both;}</style>
<div class="colblock_right"> <div class="colblock_right">
<div class="rowitem rowhead"><a>Themes</a></div> <div class="rowitem rowhead"><a>Primary Themes</a></div>
</div> </div>
<div class="colblock_right"> <div class="colblock_right">
{{range .ItemList}} {{range .PrimaryThemes}}
<div class="rowitem editable_parent" style="font-weight: normal;text-transform: none;{{if .FullImage}}background-image: url('/static/{{.FullImage}}');background-position: center;background-size: 50%;background-repeat: no-repeat;{{end}}">
<span style="float: left;">
<a href="/panel/themes/{{.Name}}" class="editable_block" style="font-size: 20px;">{{.FriendlyName}}</a><br />
<small style="margin-left: 2px;">Author: {{.Creator}}</small>
</span>
<span style="float: right;">
{{if .MobileFriendly}}<span class="username" title="Mobile Friendly">📱</span>{{end}}
{{if .Tag}}<span class="username">{{.Tag}}</span>{{end}}
{{if .Active}}<span class="username">Default</span>{{else}}<a href="/panel/themes/default/{{.Name}}?session={{$.CurrentUser.Session}}" class="username">Make Default</a>{{end}}
</span>
</div>
{{end}}
</div>
<div class="colblock_right">
<div class="rowitem rowhead"><a>Variant Themes</a></div>
</div>
<div class="colblock_right">
{{range .VariantThemes}}
<div class="rowitem editable_parent" style="font-weight: normal;text-transform: none;{{if .FullImage}}background-image: url('/static/{{.FullImage}}');background-position: center;background-size: 50%;background-repeat: no-repeat;{{end}}"> <div class="rowitem editable_parent" style="font-weight: normal;text-transform: none;{{if .FullImage}}background-image: url('/static/{{.FullImage}}');background-position: center;background-size: 50%;background-repeat: no-repeat;{{end}}">
<span style="float: left;"> <span style="float: left;">
<a href="/panel/themes/{{.Name}}" class="editable_block" style="font-size: 20px;">{{.FriendlyName}}</a><br /> <a href="/panel/themes/{{.Name}}" class="editable_block" style="font-size: 20px;">{{.FriendlyName}}</a><br />

View File

@ -4,7 +4,7 @@
<div id="nextFloat" class="next_button"><a class="next_link" href="/topic/{{.Topic.ID}}?page={{add .Page 1}}">&gt;</a></div>{{end}} <div id="nextFloat" class="next_button"><a class="next_link" href="/topic/{{.Topic.ID}}?page={{add .Page 1}}">&gt;</a></div>{{end}}
<div class="rowblock topic_block"> <div class="rowblock topic_block">
<form action='/topic/edit/submit/{{.Topic.ID}}' method="post"> <form action='/topic/edit/submit/{{.Topic.ID}}' method="post">
<div class="rowitem topic_item"{{if .Topic.Sticky}} style="background-color:#FFFFEA;"{{else if .Topic.Is_Closed}} style="background-color:#eaeaea;"{{end}}> <div class="rowitem rowhead topic_item"{{if .Topic.Sticky}} style="background-color:#FFFFEA;"{{else if .Topic.Is_Closed}} style="background-color:#eaeaea;"{{end}}>
<a class='topic_name hide_on_edit'>{{.Topic.Title}}</a> <a class='topic_name hide_on_edit'>{{.Topic.Title}}</a>
{{if .Topic.Is_Closed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>{{end}} {{if .Topic.Is_Closed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>{{end}}
{{if .CurrentUser.Perms.EditTopic}} {{if .CurrentUser.Perms.EditTopic}}
@ -21,7 +21,7 @@
<div class="rowblock post_container"> <div class="rowblock post_container">
<div class="rowitem passive editable_parent post_item" style="border-bottom: none;{{if .Topic.Avatar}}background-image:url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;{{.Topic.Css}}{{end}}"> <div class="rowitem passive editable_parent post_item" style="border-bottom: none;{{if .Topic.Avatar}}background-image:url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;{{.Topic.Css}}{{end}}">
<p class="hide_on_edit topic_content user_content" style="margin:0;padding:0;">{{.Topic.Content}}</p> <p class="hide_on_edit topic_content user_content" style="margin:0;padding:0;">{{.Topic.Content}}</p>
<textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea><br /><br /> <textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea>
<a href="/user/{{.Topic.CreatedBy}}" class="username real_username">{{.Topic.CreatedByName}}</a>&nbsp; <a href="/user/{{.Topic.CreatedBy}}" class="username real_username">{{.Topic.CreatedByName}}</a>&nbsp;
{{if .CurrentUser.Perms.LikeItem}}<a href="/topic/like/submit/{{.Topic.ID}}" class="mod_button" title="Love it" style="color:#202020;"><button class="username" style="{{if .Topic.Liked}}background-color:/*#eaffea*/#D6FFD6;{{end}}">😀</button></a>&nbsp;{{end}} {{if .CurrentUser.Perms.LikeItem}}<a href="/topic/like/submit/{{.Topic.ID}}" class="mod_button" title="Love it" style="color:#202020;"><button class="username" style="{{if .Topic.Liked}}background-color:/*#eaffea*/#D6FFD6;{{end}}">😀</button></a>&nbsp;{{end}}
{{if .CurrentUser.Perms.EditTopic}}<a href='/topic/edit/{{.Topic.ID}}' class="mod_button open_edit" style="font-weight:normal;" title="Edit Topic"><button class="username">🖊️</button></a>&nbsp;{{end}} {{if .CurrentUser.Perms.EditTopic}}<a href='/topic/edit/{{.Topic.ID}}' class="mod_button open_edit" style="font-weight:normal;" title="Edit Topic"><button class="username">🖊️</button></a>&nbsp;{{end}}
@ -29,19 +29,19 @@
{{if .CurrentUser.Perms.PinTopic}}{{if .Topic.Sticky}}<a class="mod_button" href='/topic/unstick/submit/{{.Topic.ID}}' style="font-weight:normal;" title="Unpin Topic"><button class="username" style="background-color:/*#eaffea*/#D6FFD6;">📌</button></a>{{else}}<a href='/topic/stick/submit/{{.Topic.ID}}' class="mod_button" style="font-weight:normal;" title="Pin Topic"><button class="username">📌</button></a>&nbsp;{{end}}{{end}} {{if .CurrentUser.Perms.PinTopic}}{{if .Topic.Sticky}}<a class="mod_button" href='/topic/unstick/submit/{{.Topic.ID}}' style="font-weight:normal;" title="Unpin Topic"><button class="username" style="background-color:/*#eaffea*/#D6FFD6;">📌</button></a>{{else}}<a href='/topic/stick/submit/{{.Topic.ID}}' class="mod_button" style="font-weight:normal;" title="Pin Topic"><button class="username">📌</button></a>&nbsp;{{end}}{{end}}
<a href="/report/submit/{{.Topic.ID}}?session={{.CurrentUser.Session}}&type=topic" class="mod_button report_item" style="font-weight:normal;" title="Flag Topic"><button class="username">🚩</button></a>&nbsp; <a href="/report/submit/{{.Topic.ID}}?session={{.CurrentUser.Session}}&type=topic" class="mod_button report_item" style="font-weight:normal;" title="Flag Topic"><button class="username">🚩</button></a>&nbsp;
{{if .Topic.LikeCount}}<a class="username hide_on_micro" style="float: right;color:#505050;border-left:none;padding-left:5px;padding-right:5px;font-size:17px;">{{.Topic.LikeCount}}</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;margin-left:5px;" title="Like Count">😀</a>{{end}} {{if .Topic.LikeCount}}<a class="username hide_on_micro" style="float: right;color:#505050;border-left:none;padding-left:5px;padding-right:5px;font-size:17px;">{{.Topic.LikeCount}}</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;margin-left:5px;" title="Like Count">😀</a>{{end}}
{{if .Topic.Tag}}<a class="username hide_on_micro" style="float:right;color:#505050;font-size:16px;">{{.Topic.Tag}}</a>{{else}}<a class="username hide_on_micro" style="float: right;color:#505050;border-left:none;padding-left:5px;padding-right:5px;font-size:17px;">{{.Topic.Level}}</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;" title="Level">👑</a>{{end}} {{if .Topic.Tag}}<a class="username hide_on_micro" style="float:right;color:#505050;font-size:16px;">{{.Topic.Tag}}</a>{{else}}<a class="username hide_on_micro level">{{.Topic.Level}}</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;" title="Level">👑</a>{{end}}
</div> </div>
</div><br /> </div><br />
<div class="rowblock post_container" style="overflow: hidden;">{{range .ItemList}} <div class="rowblock post_container" style="overflow: hidden;">{{range .ItemList}}
<div class="rowitem rowhead passive deletable_block editable_parent post_item" style="{{if .Avatar}}background-image:url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;{{.Css}}{{end}}"> <div class="rowitem passive deletable_block editable_parent post_item" style="{{if .Avatar}}background-image:url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;{{.Css}}{{end}}">
<p class="editable_block user_content" style="margin: 0;padding: 0;">{{.ContentHtml}}</p><br /><br /> <p class="editable_block user_content" style="margin: 0;padding: 0;">{{.ContentHtml}}</p>
<a href="/user/{{.CreatedBy}}" class="username real_username">{{.CreatedByName}}</a>&nbsp; <a href="/user/{{.CreatedBy}}" class="username real_username">{{.CreatedByName}}</a>&nbsp;
{{if $.CurrentUser.Perms.LikeItem}}<a href="/reply/like/submit/{{.ID}}" class="mod_button" title="Love it" style="color:#202020;"><button class="username" style="{{if .Liked}}background-color:/*#eaffea*/#D6FFD6;{{end}}">😀</button></a>&nbsp;{{end}} {{if $.CurrentUser.Perms.LikeItem}}<a href="/reply/like/submit/{{.ID}}" class="mod_button" title="Love it" style="color:#202020;"><button class="username" style="{{if .Liked}}background-color:/*#eaffea*/#D6FFD6;{{end}}">😀</button></a>&nbsp;{{end}}
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="mod_button" title="Edit Reply"><button class="username edit_item">🖊️</button></a>&nbsp;{{end}} {{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="mod_button" title="Edit Reply"><button class="username edit_item">🖊️</button></a>&nbsp;{{end}}
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="mod_button" title="Delete Reply"><button class="username delete_item">🗑️</button></a>&nbsp;{{end}} {{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="mod_button" title="Delete Reply"><button class="username delete_item">🗑️</button></a>&nbsp;{{end}}
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="mod_button" title="Flag Reply"><button class="username report_item">🚩</button></a>&nbsp; <a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="mod_button" title="Flag Reply"><button class="username report_item">🚩</button></a>&nbsp;
{{if .LikeCount}}<a class="username hide_on_micro" style="float: right;color:#505050;border-left:none;padding-left:5px;padding-right:5px;font-size:17px;">{{.LikeCount}}</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;margin-left:5px;" title="Like Count">😀</a>{{end}} {{if .LikeCount}}<a class="username hide_on_micro" style="float: right;color:#505050;border-left:none;padding-left:5px;padding-right:5px;font-size:17px;">{{.LikeCount}}</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;margin-left:5px;" title="Like Count">😀</a>{{end}}
{{if .Tag}}<a class="username hide_on_micro" style="float: right;color:#505050;font-size:16px;">{{.Tag}}</a>{{else}}<a class="username hide_on_micro" style="float: right;color:#505050;border-left:none;padding-left:5px;padding-right:5px;font-size:17px;">{{.Level}}</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;" title="Level">👑{{end}}</a> {{if .Tag}}<a class="username hide_on_micro" style="float: right;color:#505050;font-size:16px;">{{.Tag}}</a>{{else}}<a class="username hide_on_micro level">{{.Level}}</a><a class="username hide_on_micro" style="color:#505050;float:right;opacity:0.85;" title="Level">👑{{end}}</a>
</div> </div>
{{end}}</div> {{end}}</div>
{{if .CurrentUser.Perms.CreateReply}} {{if .CurrentUser.Perms.CreateReply}}

View File

@ -27,6 +27,7 @@ type Theme struct
MobileFriendly bool MobileFriendly bool
Disabled bool Disabled bool
HideFromThemes bool HideFromThemes bool
ForkOf string
Tag string Tag string
Settings map[string]ThemeSetting Settings map[string]ThemeSetting
Templates []TemplateMapping Templates []TemplateMapping

View File

@ -5,7 +5,7 @@
"Creator": "Azareal", "Creator": "Azareal",
"Disabled": true, "Disabled": true,
"HideFromThemes": true, "HideFromThemes": true,
"Tag": "WIP", "Tag": "🏗️",
"Templates": [ "Templates": [
{ {
"Name": "topic", "Name": "topic",

View File

@ -450,6 +450,15 @@ button .big { padding: 6px; }*/
font-size: 15px; font-size: 15px;
} }
.postQuote {
padding: 5px;
border: 1px solid rgb(200,200,200);
display: inline-block;
margin-bottom: 5px;
width: 100%;
background: rgb(250,250,250);
}
.threadHidden { background: orange; } .threadHidden { background: orange; }
.threadDeleted { background: rgba(255,0,0,0.5); } .threadDeleted { background: rgba(255,0,0,0.5); }

View File

@ -4,6 +4,7 @@
"Version": "Coming Soon", "Version": "Coming Soon",
"Creator": "Azareal", "Creator": "Azareal",
"FullImage": "cosmo-conflux.png", "FullImage": "cosmo-conflux.png",
"ForkOf": "cosmo",
"MobileFriendly": true, "MobileFriendly": true,
"Templates": [ "Templates": [
{ {

View File

@ -439,6 +439,16 @@ button .big { padding: 6px; }*/
font-size: 15px; font-size: 15px;
} }
.postQuote {
border-radius: 4px;
padding: 5px;
border: 1px solid rgb(200,200,200);
display: inline-block;
margin-bottom: 5px;
width: 100%;
background: rgb(250,250,250);
}
.threadHidden { background: orange; } .threadHidden { background: orange; }
.threadDeleted { background: rgba(255,0,0,0.5); } .threadDeleted { background: rgba(255,0,0,0.5); }

View File

@ -353,6 +353,19 @@ button.username
position: relative; position: relative;
top: -0.25px; top: -0.25px;
} }
.postQuote {
border: rgb(200,200,210);
background: rgb(245,245,255);
padding: 3px;
margin: 0px;
display: inline-block;
width: 100%;
margin-bottom: 5px;
border-style: solid;
border-width: 1px;
}
.tag-mini .tag-mini
{ {
text-transform: none; text-transform: none;

View File

@ -0,0 +1,497 @@
* {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
body
{
font-family: cursive;
padding-bottom: 8px;
}
/* Patch for Edge */
@supports (-ms-ime-align:auto) {
.user_content { font-family: Segoe UI Emoji, arial; }
}
ul
{
padding-left: 0px;
padding-right: 0px;
height: 28px;
list-style-type: none;
border: 1px solid #ccc;
background-color: white;
}
li
{
height: 26px;
padding-left: 10px;
padding-top: 5px;
padding-bottom: 5px;
font-weight: bold;
text-transform: uppercase;
}
li:hover { background: rgb(250,250,250); }
li a
{
text-decoration: none;
color: #515151;
}
/*li a:hover { color: #7a7a7a; }*/
.menu_left
{
float: left;
border-right: 1px solid #ccc;
padding-right: 10px;
font-family: cursive;
padding-top: 2px;
}
.menu_right
{
float: right;
border-left: 1px solid #ccc;
padding-right: 10px;
}
.menu_alerts {
padding-left: 7px;
padding-top: 2px;
color: rgb(80,80,80);
}
.menu_alerts .alert_counter {
position:relative;
font-size: 9px;
top: -24px;
background-color: rgb(140,0,0);
color: white;
padding: 3px;
width: 14px;
left: 10px;
line-height: 8px;
border-radius: 20px;
padding-top: 2.5px;
height: 14px;
opacity: 0.8;
text-align: center;
}
.menu_alerts .alert_counter:empty {
display: none;
}
.selectedAlert {
background: white;
color: black;
}
.selectedAlert:hover {
background: white;
color: black;
}
.menu_alerts .alertList {
display: none;
text-transform: none;
}
.selectedAlert .alertList {
position: absolute;
top: 43px;
display: block;
background: white;
font-size: 10px;
line-height: 16px;
width: 135px;
right: calc(5% + 7px);
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
}
.alertItem {
padding: 8px;
overflow: hidden;
text-overflow: ellipsis;
}
.alertItem.withAvatar {
background-size: auto 56px;
background-repeat: no-repeat;
text-align: right;
padding-right: 12px;
height: 46px;
}
.alertItem.withAvatar:not(:last-child) {
border-bottom: 1px solid rgb(230,230,230);
}
.alertItem.withAvatar .text {
overflow: hidden;
text-overflow: ellipsis;
float: right;
width: calc(100% - 20px);
height: 30px;
}
.container
{
width: 90%;
padding: 0px;
margin-left: auto;
margin-right: auto;
}
.rowblock
{
border: 1px solid #ccc;
width: 100%;
padding: 0px;
padding-top: 0px;
}
.rowblock:empty { display: none; }
.colblock_left
{
border: 1px solid #ccc;
padding: 0px;
padding-top: 0px;
width: 30%;
float: left;
margin-right: 8px;
}
.colblock_right
{
border: 1px solid #ccc;
padding: 0px;
padding-top: 0px;
width: 65%;
overflow: hidden;
word-wrap: break-word;
}
.colblock_left:empty { display: none; }
.colblock_right:empty { display: none; }
.rowhead { font-family: cursive; }
.rowitem
{
width: 100%;
padding-left: 8px;
padding-right: 8px;
padding-top: 17px;
padding-bottom: 12px;
font-weight: bold;
text-transform: uppercase;
background-color: white;
}
.rowitem.passive
{
font-weight: normal;
text-transform: none;
}
.rowitem:not(:last-child)
{
border-bottom: 1px dotted #ccc;
}
.rowitem a
{
text-decoration: none;
color: black;
}
.rowitem a:hover { color: silver; }
.opthead { display: none; }
.col_left
{
width: 30%;
float: left;
}
.col_right
{
width: 69%;
overflow: hidden;
}
.colitem
{
padding-left: 8px;
padding-right: 8px;
padding-top: 17px;
padding-bottom: 12px;
font-weight: bold;
text-transform: uppercase;
}
.colitem.passive
{
font-weight: normal;
text-transform: none;
}
.colitem a
{
text-decoration: none;
color: black;
}
.colitem a:hover { color: silver; }
.formrow
{
width: 100%;
background-color: white;
}
/* Clearfix */
.formrow:before, .formrow:after {
content: " ";
display: table;
}
.formrow:after { clear: both; }
.formrow:not(:last-child)
{
border-bottom: 1px dotted #ccc;
}
.formitem
{
float: left;
padding-left: 8px;
padding-right: 8px;
padding-top: 13px;
padding-bottom: 8px;
font-weight: bold;
}
.formitem:first-child { font-weight: bold; }
.formitem:not(:last-child) { border-right: 1px dotted #ccc; }
.formitem.invisible_border { border: none; }
/* Mostly for textareas */
.formitem:only-child { width: 100%; }
.formitem textarea
{
width: 100%;
height: 100px;
outline-color: #8e8e8e;
}
.formitem:has-child()
{
margin: 0 auto;
float: none;
}
button
{
background: white;
border: 1px solid #8e8e8e;
}
/* Topics */
.topic_status
{
text-transform: none;
margin-left: 8px;
padding-left: 2px;
padding-right: 2px;
padding-top: 2px;
padding-bottom: 2px;
background-color: #E8E8E8; /* 232,232,232. All three RGB colours being the same seems to create a shade of gray */
color: #505050; /* 80,80,80 */
border-radius: 2px;
}
.topic_status:empty { display: none; }
.username
{
text-transform: none;
margin-left: 0px;
padding-left: 0px;
padding-right: 0px;
padding-top: 2px;
padding-bottom: 2px;
color: #505050; /* 80,80,80 */
font-size: 15px;
background: none;
}
button.username
{
position: relative;
top: -0.25px;
}
.username.level { color: #303030; }
.username.real_username { color: #404040; font-size: 17px; padding-right: 4px; }
.username.real_username:hover { color: black; }
.tag-text {
padding-top: 23px;
display: inline-block;
}
.post_item > .username {
padding-top: 23px;
display: inline-block;
}
.tag-mini
{
text-transform: none;
margin-left: 0px;
padding-left: 3px;
padding-right: 3px;
padding-top: 1.5px;
padding-bottom: 0px;
color: #505050; /* 80,80,80 */
background-color: #FFFFFF;
border-style: dotted;
border-color: #505050; /* 232,232,232. All three RGB colours being the same seems to create a shade of gray */
border-width: 1px;
font-size: 10px;
}
.post_item > .mod_button > button {
font-size: 15px;
color: #202020;
opacity: 0.7;
border: none;
}
.post_item > .mod_button > button:hover {
opacity: 0.9;
}
.postQuote {
border: 1px solid #ccc;
background: white;
padding: 3px;
margin: 0px;
display: inline-block;
width: 100%;
margin-bottom: 5px;
}
.level {
float: right;
color: #505050;
border-left: none;
padding-left: 3px;
padding-right: 5px;
font-size: 16px;
}
.show_on_edit { display: none; }
.alert
{
display: block;
padding: 5px;
margin-bottom: 10px;
border: 1px solid #ccc;
}
.alert_success
{
display: block;
padding: 5px;
border: 1px solid A2FC00;
margin-bottom: 10px;
background-color: DAF7A6;
}
.alert_error
{
display: block;
padding: 5px;
border: 1px solid #FF004B;
margin-bottom: 8px;
background-color: #FEB7CC;
}
.prev_button, .next_button {
position: fixed;
top: 50%;
font-size: 30px;
border-width: 1px;
background-color: #FFFFFF;
border-style: dotted;
border-color: #505050;
padding: 0px;
padding-left: 5px;
padding-right: 5px;
z-index: 100;
}
.prev_button a, .next_button a {
line-height: 28px;
margin-top: 2px;
margin-bottom: 0px;
display: block;
text-decoration: none;
color: #505050;
}
.prev_button { left: 14px; }
.next_button { right: 14px; }
@media (max-width: 880px) {
li { height: 25px; font-size: 15px; padding-left: 7px; }
ul { height: 26px; margin-top: 8px; }
.menu_left { padding-right: 7px; }
.menu_right { padding-right: 7px; }
body { padding-left: 4px; padding-right: 4px; margin: 0px !important; width: 100% !important; height: 100% !important; overflow-x: hidden; }
.container { width: auto; }
.selectedAlert .alertList { top: 33px; right: 4px; }
}
@media (max-width: 810px) {
li { font-weight: normal; text-transform: none; }
.rowitem { text-transform: none; }
/*.rowhead { font-family: arial; }
.menu_left { font-family: arial; }*/
body { font-family: arial; }
.level { font-size: 17px; }
}
@media (max-width: 620px) {
li
{
padding-left: 5px;
padding-top: 2px;
padding-bottom: 2px;
height: 23px;
}
ul { height: 24px; }
.menu_left { padding-right: 5px; }
.menu_right { padding-right: 5px; }
.menu_create_topic { display: none;}
.menu_alerts { padding-left: 4px; padding-right: 4px; }
.hide_on_mobile { display: none; }
.prev_button, .next_button { top: auto; bottom: 5px; }
}
@media (max-width: 470px) {
.menu_overview { display: none; }
.menu_profile { display: none; }
.hide_on_micro { display: none; }
.post_container {
overflow: visible !important;
}
.post_item {
background-position: 0px 2px !important;
background-size: 64px 64px !important;
padding-left: 2px !important;
min-height: 96px;
position: relative !important;
}
.post_item > .user_content {
margin-left: 75px !important;
width: 100% !important;
}
.post_item > .mod_button {
float: right !important;
margin-left: 2px !important;
position: relative;
top: -14px;
}
.post_item > .mod_button > button {
opacity: 1;
}
.post_item > .real_username {
position: absolute;
top: 70px;
float: left;
margin-top: -2px;
padding-top: 3px !important;
margin-right: 2px;
width: 60px;
font-size: 15px;
text-align: center;
}
.container { width: 100% !important; }
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB

View File

@ -0,0 +1,10 @@
{
"Name": "tempra-cursive",
"FriendlyName": "Tempra Cursive",
"Version": "0.0.1",
"Creator": "Azareal",
"FullImage": "tempra-cursive.png",
"ForkOf": "tempra-simple",
"Tag": "🏗️",
"MobileFriendly": true
}

View File

@ -316,6 +316,12 @@ button.username
.username.level { color: #303030; } .username.level { color: #303030; }
.username.real_username { color: #404040; font-size: 17px; } .username.real_username { color: #404040; font-size: 17px; }
.username.real_username:hover { color: black; } .username.real_username:hover { color: black; }
.post_item > .username {
margin-top: 44.2px;
display: inline-block;
}
.tag-mini .tag-mini
{ {
text-transform: none; text-transform: none;
@ -341,6 +347,25 @@ button.username
opacity: 0.9; opacity: 0.9;
} }
.postQuote {
border: 1px solid #ccc;
background: white;
padding: 3px;
margin: 0px;
display: inline-block;
width: 100%;
margin-bottom: 5px;
}
.level {
float: right;
color: #505050;
border-left: none;
padding-left: 5px;
padding-right: 5px;
font-size: 17px;
}
.show_on_edit { display: none; } .show_on_edit { display: none; }
.alert .alert
{ {
@ -401,11 +426,7 @@ button.username
} }
@media (max-width: 810px) { @media (max-width: 810px) {
li li { font-weight: normal; text-transform: none; }
{
font-weight: normal;
text-transform: none;
}
.rowitem { text-transform: none; } .rowitem { text-transform: none; }
} }
@ -450,9 +471,7 @@ button.username
position: relative; position: relative;
top: -14px; top: -14px;
} }
.post_item > .mod_button > button { .post_item > .mod_button > button { opacity: 1; }
opacity: 1;
}
.post_item > .real_username { .post_item > .real_username {
position: absolute; position: absolute;
top: 70px; top: 70px;