Compare commits
No commits in common. "865b37cf89d349a18ace9ee0f7f439d4f6c25676" and "2a87ebdfd6e6fa19b772fc3c06f9ecfff46a3d64" have entirely different histories.
865b37cf89
...
2a87ebdfd6
|
@ -42,14 +42,10 @@ func NewHandle(c *gin.Context, scene int, theme string) *Handle {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *Handle) PushHandleFn(fns ...func(*Handle)) {
|
||||
h.HandleFns = append(h.HandleFns, fns...)
|
||||
}
|
||||
|
||||
func (h *Handle) AutoCal(name string, fn func(*Handle) string) {
|
||||
func (h *Handle) AutoCal(name string, fn func() string) {
|
||||
v, ok := reload.GetStr(name)
|
||||
if !ok {
|
||||
v = fn(h)
|
||||
v = fn()
|
||||
reload.SetStr(name, v)
|
||||
}
|
||||
h.GinH[name] = v
|
||||
|
@ -76,9 +72,9 @@ func (h *Handle) Render() {
|
|||
for _, fn := range h.HandleFns {
|
||||
fn(h)
|
||||
}
|
||||
h.AutoCal("siteIcon", CalSiteIcon)
|
||||
h.AutoCal("customLogo", CalCustomLogo)
|
||||
h.AutoCal("customCss", CalCustomCss)
|
||||
h.AutoCal("siteIcon", h.CalSiteIcon)
|
||||
h.AutoCal("customLogo", h.CalCustomLogo)
|
||||
h.AutoCal("customCss", h.CalCustomCss)
|
||||
h.CalBodyClass()
|
||||
|
||||
h.C.HTML(h.Code, h.Templ, h.GinH)
|
||||
|
@ -89,7 +85,7 @@ type HandleFn[T any] func(T)
|
|||
type HandlePipeFn[T any] func(HandleFn[T], T)
|
||||
|
||||
// HandlePipe 方便把功能写在其它包里
|
||||
func HandlePipe[T any](initial func(T), fns ...HandlePipeFn[T]) HandleFn[T] {
|
||||
func HandlePipe[T any](fns []HandlePipeFn[T], initial func(T)) HandleFn[T] {
|
||||
return slice.ReverseReduce(fns, func(next HandlePipeFn[T], f func(t T)) func(t T) {
|
||||
return func(t T) {
|
||||
next(f, t)
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"github.com/fthvgb1/wp-go/internal/pkg/cache"
|
||||
)
|
||||
|
||||
func CalCustomCss(h *Handle) (r string) {
|
||||
func (h *Handle) CalCustomCss() (r string) {
|
||||
if h.ThemeMods.CustomCssPostId < 1 {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/fthvgb1/wp-go/internal/wpconfig"
|
||||
)
|
||||
|
||||
func CalCustomLogo(h *Handle) (r string) {
|
||||
func (h *Handle) CalCustomLogo() (r string) {
|
||||
id := uint64(h.ThemeMods.CustomLogo)
|
||||
if id < 1 {
|
||||
id = str.ToInteger[uint64](wpconfig.GetOption("site_logo"), 0)
|
||||
|
|
|
@ -17,12 +17,19 @@ type DetailHandle struct {
|
|||
CommentRender plugins.CommentHtml
|
||||
Comments []models.Comments
|
||||
Post models.Posts
|
||||
Pipes []HandlePipeFn[*DetailHandle]
|
||||
}
|
||||
|
||||
func NewDetailHandle(handle *Handle) *DetailHandle {
|
||||
return &DetailHandle{Handle: handle}
|
||||
}
|
||||
|
||||
func (d *DetailHandle) Pipe(calls ...HandlePipeFn[*DetailHandle]) {
|
||||
HandlePipe[*DetailHandle](append(calls, d.Pipes...), func(d *DetailHandle) {
|
||||
d.Render()
|
||||
})(d)
|
||||
}
|
||||
|
||||
func (d *DetailHandle) BuildDetailData() (err error) {
|
||||
d.GinH["title"] = wpconfig.GetOption("blogname")
|
||||
err = d.CheckAndGetPost()
|
||||
|
|
|
@ -22,12 +22,19 @@ type IndexHandle struct {
|
|||
PageEle pagination.Elements
|
||||
TotalRows int
|
||||
PostsPlugins map[string]Plugin[models.Posts, *Handle]
|
||||
Pipes []HandlePipeFn[*IndexHandle]
|
||||
}
|
||||
|
||||
func NewIndexHandle(handle *Handle) *IndexHandle {
|
||||
return &IndexHandle{Handle: handle}
|
||||
}
|
||||
|
||||
func (i *IndexHandle) Pipe(calls ...HandlePipeFn[*IndexHandle]) {
|
||||
HandlePipe[*IndexHandle](append(calls, i.Pipes...), func(i *IndexHandle) {
|
||||
i.Render()
|
||||
})(i)
|
||||
}
|
||||
|
||||
func (i *IndexHandle) ParseIndex(parm *IndexParams) (err error) {
|
||||
i.Param = parm
|
||||
switch i.Scene {
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
var sizes = []string{"site_icon-270", "site_icon-32", "site_icon-192", "site_icon-180"}
|
||||
|
||||
func CalSiteIcon(h *Handle) (r string) {
|
||||
func (h *Handle) CalSiteIcon() (r string) {
|
||||
id := str.ToInteger[uint64](wpconfig.GetOption("site_icon"), 0)
|
||||
if id < 1 {
|
||||
return
|
||||
|
|
|
@ -3,13 +3,12 @@ package twentyfifteen
|
|||
import (
|
||||
"fmt"
|
||||
"github.com/fthvgb1/wp-go/helper/slice"
|
||||
"github.com/fthvgb1/wp-go/internal/theme/common"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func colorSchemeCss(h *common.Handle) string {
|
||||
s := slice.Filter([]string{calColorSchemeCss(h), calSidebarTextColorCss(h), calHeaderBackgroundColorCss(h)}, func(s string) bool {
|
||||
func (h *handle) colorSchemeCss() string {
|
||||
s := slice.Filter([]string{h.calColorSchemeCss(), h.calSidebarTextColorCss(), h.calHeaderBackgroundColorCss()}, func(s string) bool {
|
||||
return s != ""
|
||||
})
|
||||
if len(s) < 1 {
|
||||
|
@ -17,9 +16,9 @@ func colorSchemeCss(h *common.Handle) string {
|
|||
}
|
||||
return fmt.Sprintf(`<style id='%s-inline-css'%s>\n%s\n</style>`, "twentyfifteen-style", "", strings.Join(s, "\n"))
|
||||
}
|
||||
func calColorSchemeCss(h *common.Handle) (r string) {
|
||||
color := getColorScheme(h)
|
||||
if "default" == h.ThemeMods.ColorScheme || len(color) < 1 {
|
||||
func (h *handle) calColorSchemeCss() (r string) {
|
||||
color := h.getColorScheme()
|
||||
if "default" == h.IndexHandle.ThemeMods.ColorScheme || len(color) < 1 {
|
||||
return
|
||||
}
|
||||
textColorRgb := slice.ToAnySlice(Hex2RgbUint8(color[3]))
|
||||
|
@ -46,31 +45,31 @@ func calColorSchemeCss(h *common.Handle) (r string) {
|
|||
return
|
||||
}
|
||||
|
||||
func calSidebarTextColorCss(h *common.Handle) (r string) {
|
||||
colors := getColorScheme(h)
|
||||
if h.ThemeMods.SidebarTextcolor == "" || h.ThemeMods.SidebarTextcolor == colors[4] {
|
||||
func (h *handle) calSidebarTextColorCss() (r string) {
|
||||
colors := h.getColorScheme()
|
||||
if h.IndexHandle.ThemeMods.SidebarTextcolor == "" || h.IndexHandle.ThemeMods.SidebarTextcolor == colors[4] {
|
||||
return
|
||||
}
|
||||
linkColorRgb := Hex2RgbUint8(h.ThemeMods.SidebarTextcolor)
|
||||
linkColorRgb := Hex2RgbUint8(h.IndexHandle.ThemeMods.SidebarTextcolor)
|
||||
color := slice.ToAnySlice(linkColorRgb)
|
||||
textColor := fmt.Sprintf(`rgba( %[1]v, %[2]v, %[3]v, 0.7)`, color...)
|
||||
borderColor := fmt.Sprintf(`rgba( %[1]v, %[2]v, %[3]v, 0.1)`, color...)
|
||||
borderFocusColor := fmt.Sprintf(`rgba( %[1]v, %[2]v, %[3]v, 0.3)`, color...)
|
||||
r = fmt.Sprintf(sidebarTextColorTemplate, h.ThemeMods.SidebarTextcolor, textColor, borderColor, borderFocusColor)
|
||||
r = fmt.Sprintf(sidebarTextColorTemplate, h.IndexHandle.ThemeMods.SidebarTextcolor, textColor, borderColor, borderFocusColor)
|
||||
return
|
||||
}
|
||||
|
||||
func calHeaderBackgroundColorCss(h *common.Handle) (r string) {
|
||||
colors := getColorScheme(h)
|
||||
if h.ThemeMods.HeaderBackgroundColor == "" || h.ThemeMods.HeaderBackgroundColor == colors[1] {
|
||||
func (h *handle) calHeaderBackgroundColorCss() (r string) {
|
||||
colors := h.getColorScheme()
|
||||
if h.IndexHandle.ThemeMods.HeaderBackgroundColor == "" || h.IndexHandle.ThemeMods.HeaderBackgroundColor == colors[1] {
|
||||
return
|
||||
}
|
||||
r = fmt.Sprintf(headerBackgroundColorCssTemplate, h.ThemeMods.HeaderBackgroundColor, h.ThemeMods.HeaderBackgroundColor)
|
||||
r = fmt.Sprintf(headerBackgroundColorCssTemplate, h.IndexHandle.ThemeMods.HeaderBackgroundColor, h.IndexHandle.ThemeMods.HeaderBackgroundColor)
|
||||
return
|
||||
}
|
||||
|
||||
func getColorScheme(h *common.Handle) (r []string) {
|
||||
x, ok := colorscheme[h.ThemeMods.ColorScheme]
|
||||
func (h *handle) getColorScheme() (r []string) {
|
||||
x, ok := colorscheme[h.IndexHandle.ThemeMods.ColorScheme]
|
||||
if ok {
|
||||
r = x.Colors
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"github.com/fthvgb1/wp-go/helper"
|
||||
"github.com/fthvgb1/wp-go/helper/maps"
|
||||
str "github.com/fthvgb1/wp-go/helper/strings"
|
||||
"github.com/fthvgb1/wp-go/internal/theme/common"
|
||||
)
|
||||
|
||||
var postx = map[string]string{
|
||||
|
@ -30,30 +29,30 @@ var repeat = map[string]string{
|
|||
"no-repeat": "no-repeat",
|
||||
}
|
||||
|
||||
func CalCustomBackGround(h *common.Handle) (r string) {
|
||||
if h.ThemeMods.BackgroundImage == "" && h.ThemeMods.BackgroundColor == themesupport.CustomBackground.DefaultColor {
|
||||
func (h *handle) CalCustomBackGround() (r string) {
|
||||
if h.IndexHandle.ThemeMods.BackgroundImage == "" && h.IndexHandle.ThemeMods.BackgroundColor == themesupport.CustomBackground.DefaultColor {
|
||||
return
|
||||
}
|
||||
s := str.NewBuilder()
|
||||
if h.ThemeMods.BackgroundImage != "" {
|
||||
s.Sprintf(` background-image: url("%s");`, helper.CutUrlHost(h.ThemeMods.BackgroundImage))
|
||||
if h.IndexHandle.ThemeMods.BackgroundImage != "" {
|
||||
s.Sprintf(` background-image: url("%s");`, helper.CutUrlHost(h.IndexHandle.ThemeMods.BackgroundImage))
|
||||
}
|
||||
backgroundPositionX := helper.Defaults(h.ThemeMods.BackgroundPositionX, themesupport.CustomBackground.DefaultPositionX)
|
||||
backgroundPositionX := helper.Defaults(h.IndexHandle.ThemeMods.BackgroundPositionX, themesupport.CustomBackground.DefaultPositionX)
|
||||
backgroundPositionX = maps.WithDefaultVal(postx, backgroundPositionX, "left")
|
||||
|
||||
backgroundPositionY := helper.Defaults(h.ThemeMods.BackgroundPositionY, themesupport.CustomBackground.DefaultPositionY)
|
||||
backgroundPositionY := helper.Defaults(h.IndexHandle.ThemeMods.BackgroundPositionY, themesupport.CustomBackground.DefaultPositionY)
|
||||
backgroundPositionY = maps.WithDefaultVal(posty, backgroundPositionY, "top")
|
||||
positon := fmt.Sprintf(" background-position: %s %s;", backgroundPositionX, backgroundPositionY)
|
||||
|
||||
siz := helper.DefaultVal(h.ThemeMods.BackgroundSize, themesupport.CustomBackground.DefaultSize)
|
||||
siz := helper.DefaultVal(h.IndexHandle.ThemeMods.BackgroundSize, themesupport.CustomBackground.DefaultSize)
|
||||
siz = maps.WithDefaultVal(size, siz, "auto")
|
||||
siz = fmt.Sprintf(" background-size: %s;", siz)
|
||||
|
||||
repeats := helper.Defaults(h.ThemeMods.BackgroundRepeat, themesupport.CustomBackground.DefaultRepeat)
|
||||
repeats := helper.Defaults(h.IndexHandle.ThemeMods.BackgroundRepeat, themesupport.CustomBackground.DefaultRepeat)
|
||||
repeats = maps.WithDefaultVal(repeat, repeats, "repeat")
|
||||
repeats = fmt.Sprintf(" background-repeat: %s;", repeats)
|
||||
|
||||
attachment := helper.Defaults(h.ThemeMods.BackgroundAttachment, themesupport.CustomBackground.DefaultAttachment)
|
||||
attachment := helper.Defaults(h.IndexHandle.ThemeMods.BackgroundAttachment, themesupport.CustomBackground.DefaultAttachment)
|
||||
attachment = helper.Or(attachment == "fixed", "fixed", "scroll")
|
||||
attachment = fmt.Sprintf(" background-attachment: %s;", attachment)
|
||||
s.WriteString(positon, siz, repeats, attachment)
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
str "github.com/fthvgb1/wp-go/helper/strings"
|
||||
"github.com/fthvgb1/wp-go/internal/cmd/reload"
|
||||
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
|
||||
"github.com/fthvgb1/wp-go/internal/theme/common"
|
||||
)
|
||||
|
||||
var style = `<style type="text/css" id="twentyfifteen-header-css">`
|
||||
|
@ -83,20 +82,20 @@ var imgStyle = `.site-header {
|
|||
|
||||
var header = reload.Vars(constraints.Defaults)
|
||||
|
||||
func calCustomHeader(h *common.Handle) (r string, rand bool) {
|
||||
img, rand := h.GetCustomHeader()
|
||||
if img.Path == "" && h.DisplayHeaderText() {
|
||||
func (h *handle) CalCustomHeader() (r string, rand bool) {
|
||||
img, rand := h.IndexHandle.GetCustomHeader()
|
||||
if img.Path == "" && h.IndexHandle.DisplayHeaderText() {
|
||||
return
|
||||
}
|
||||
ss := str.NewBuilder()
|
||||
ss.WriteString(style)
|
||||
if img.Path == "" && !h.DisplayHeaderText() {
|
||||
if img.Path == "" && !h.IndexHandle.DisplayHeaderText() {
|
||||
ss.WriteString(defaultTextStyle)
|
||||
}
|
||||
if img.Path != "" {
|
||||
ss.Sprintf(imgStyle, img.Path, img.Path)
|
||||
}
|
||||
if !h.DisplayHeaderText() {
|
||||
if !h.IndexHandle.DisplayHeaderText() {
|
||||
ss.WriteString(`.site-title,
|
||||
.site-description {
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
|
@ -108,15 +107,15 @@ func calCustomHeader(h *common.Handle) (r string, rand bool) {
|
|||
return
|
||||
}
|
||||
|
||||
func customHeader(h *common.Handle) {
|
||||
func (h *handle) CustomHeader() {
|
||||
headers := header.Load()
|
||||
if headers == constraints.Defaults {
|
||||
headerss, rand := calCustomHeader(h)
|
||||
headerss, rand := h.CalCustomHeader()
|
||||
headers = headerss
|
||||
if !rand {
|
||||
header.Store(headers)
|
||||
}
|
||||
}
|
||||
h.GinH["customHeader"] = headers
|
||||
h.IndexHandle.GinH["customHeader"] = headers
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{template "layout/base" .}}
|
||||
|
||||
{{define "content"}}
|
||||
{{ if gt .post.Id 0}}
|
||||
{{ if .post.PostContent}}
|
||||
<div id="primary" class="content-area">
|
||||
<main id="main" class="site-main">
|
||||
<article id="post-{{.post.Id}}"
|
||||
|
|
|
@ -28,31 +28,36 @@ func Init(fs embed.FS) {
|
|||
logs.ErrPrintln(err, "解析colorscheme失败")
|
||||
}
|
||||
|
||||
var detailPipe = common.HandlePipe(func(d *common.DetailHandle) {
|
||||
d.Render()
|
||||
}, detail)
|
||||
var indexPipe = common.HandlePipe(func(i *common.IndexHandle) {
|
||||
i.Render()
|
||||
}, index)
|
||||
type handle struct {
|
||||
*common.IndexHandle
|
||||
*common.DetailHandle
|
||||
}
|
||||
|
||||
func newHandle(iHandle *common.IndexHandle, dHandle *common.DetailHandle) *handle {
|
||||
return &handle{iHandle, dHandle}
|
||||
}
|
||||
|
||||
func Hook(h *common.Handle) {
|
||||
h.WidgetAreaData()
|
||||
h.GetPassword()
|
||||
h.AutoCal("colorScheme", colorSchemeCss)
|
||||
h.AutoCal("customBackground", CalCustomBackGround)
|
||||
h.PushHandleFn(customHeader)
|
||||
switch h.Scene {
|
||||
case constraints.Detail:
|
||||
detailPipe(common.NewDetailHandle(h))
|
||||
default:
|
||||
indexPipe(common.NewIndexHandle(h))
|
||||
handle := newHandle(common.NewIndexHandle(h), common.NewDetailHandle(h))
|
||||
if h.Scene == constraints.Detail {
|
||||
handle.Detail()
|
||||
return
|
||||
}
|
||||
handle.Index()
|
||||
}
|
||||
|
||||
func index(next common.HandleFn[*common.IndexHandle], i *common.IndexHandle) {
|
||||
i.Indexs()
|
||||
func (h *handle) Index() {
|
||||
h.CustomHeader()
|
||||
h.IndexHandle.AutoCal("colorScheme", h.colorSchemeCss)
|
||||
h.IndexHandle.AutoCal("customBackground", h.CalCustomBackGround)
|
||||
h.Indexs()
|
||||
}
|
||||
|
||||
func detail(fn common.HandleFn[*common.DetailHandle], d *common.DetailHandle) {
|
||||
d.Details()
|
||||
func (h *handle) Detail() {
|
||||
h.CustomHeader()
|
||||
h.IndexHandle.AutoCal("colorScheme", h.colorSchemeCss)
|
||||
h.IndexHandle.AutoCal("customBackground", h.CalCustomBackGround)
|
||||
h.Details()
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@ package twentyseventeen
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/fthvgb1/wp-go/helper"
|
||||
"github.com/fthvgb1/wp-go/helper/maps"
|
||||
"github.com/fthvgb1/wp-go/internal/cmd/reload"
|
||||
"github.com/fthvgb1/wp-go/helper/slice"
|
||||
"github.com/fthvgb1/wp-go/internal/pkg/cache"
|
||||
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
|
||||
"github.com/fthvgb1/wp-go/internal/pkg/logs"
|
||||
"github.com/fthvgb1/wp-go/internal/pkg/models"
|
||||
"github.com/fthvgb1/wp-go/internal/plugins"
|
||||
"github.com/fthvgb1/wp-go/internal/theme/common"
|
||||
|
@ -27,27 +28,19 @@ var paginate = func() plugins.PageEle {
|
|||
return p
|
||||
}()
|
||||
|
||||
var detailPipe = common.HandlePipe(func(d *common.DetailHandle) {
|
||||
d.Render()
|
||||
}, detail)
|
||||
var indexPipe = common.HandlePipe(func(i *common.IndexHandle) {
|
||||
i.Render()
|
||||
}, index)
|
||||
|
||||
func Hook(h *common.Handle) {
|
||||
h.WidgetAreaData()
|
||||
h.GetPassword()
|
||||
h.PushHandleFn(calClass)
|
||||
h.GinH["HeaderImage"] = getHeaderImage(h)
|
||||
switch h.Scene {
|
||||
case constraints.Detail:
|
||||
detailPipe(common.NewDetailHandle(h))
|
||||
default:
|
||||
indexPipe(common.NewIndexHandle(h))
|
||||
h.HandleFns = append(h.HandleFns, calClass)
|
||||
h.GinH["HeaderImage"] = getHeaderImage(h.C)
|
||||
if h.Scene == constraints.Detail {
|
||||
common.NewDetailHandle(h).Pipe(detail)
|
||||
return
|
||||
}
|
||||
common.NewIndexHandle(h).Pipe(index)
|
||||
}
|
||||
|
||||
var listPostsPlugins = func() map[string]common.Plugin[models.Posts, *common.Handle] {
|
||||
var pluginFns = func() map[string]common.Plugin[models.Posts, *common.Handle] {
|
||||
return maps.Merge(common.ListPostPlugins(), map[string]common.Plugin[models.Posts, *common.Handle]{
|
||||
"twentyseventeen_postThumbnail": postThumbnail,
|
||||
})
|
||||
|
@ -62,7 +55,7 @@ func index(next common.HandleFn[*common.IndexHandle], i *common.IndexHandle) {
|
|||
i.C.HTML(i.Code, i.Templ, i.GinH)
|
||||
return
|
||||
}
|
||||
i.PostsPlugins = listPostsPlugins
|
||||
i.PostsPlugins = pluginFns
|
||||
i.PageEle = paginate
|
||||
next(i)
|
||||
}
|
||||
|
@ -118,29 +111,16 @@ func postThumbnail(next common.Fn[models.Posts], h *common.Handle, t models.Post
|
|||
return next(t)
|
||||
}
|
||||
|
||||
var header = reload.Vars(models.PostThumbnail{})
|
||||
|
||||
func getHeaderImage(h *common.Handle) (r models.PostThumbnail) {
|
||||
img := header.Load()
|
||||
r.Sizes = "100vw"
|
||||
if img.Path == "" {
|
||||
image, rand := h.GetCustomHeader()
|
||||
if !rand {
|
||||
if image.Path == "" {
|
||||
r.Path = helper.CutUrlHost(h.ThemeMods.ThemeSupport.CustomHeader.DefaultImage)
|
||||
r.Width = 2000
|
||||
r.Height = 1200
|
||||
header.Store(r)
|
||||
return
|
||||
}
|
||||
r = image
|
||||
r.Sizes = "100vw"
|
||||
header.Store(r)
|
||||
return
|
||||
}
|
||||
img = image
|
||||
func getHeaderImage(c *gin.Context) (r models.PostThumbnail) {
|
||||
r.Path = "/wp-content/themes/twentyseventeen/assets/images/header.jpg"
|
||||
r.Width = 2000
|
||||
r.Height = 1200
|
||||
hs, err := cache.GetHeaderImages(c, ThemeName)
|
||||
if err != nil {
|
||||
logs.ErrPrintln(err, "获取页眉背景图失败")
|
||||
} else if len(hs) > 0 && err == nil {
|
||||
_, r = slice.Rand(hs)
|
||||
}
|
||||
r = img
|
||||
r.Sizes = "100vw"
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user