2018-10-27 03:21:02 +00:00
package guilds // import "github.com/Azareal/Gosora/extend/guilds/lib"
2017-11-10 03:33:11 +00:00
import (
"bytes"
"context"
"database/sql"
"errors"
"html/template"
"net/http"
"strconv"
"strings"
2019-04-19 06:36:26 +00:00
c "github.com/Azareal/Gosora/common"
2019-04-19 09:34:16 +00:00
"github.com/Azareal/Gosora/routes"
2017-11-10 03:33:11 +00:00
)
2017-11-11 04:06:16 +00:00
// A blank list to fill out that parameter in Page for routes which don't use it
var tList [ ] interface { }
2017-11-10 03:33:11 +00:00
var ListStmt * sql . Stmt
var MemberListStmt * sql . Stmt
var MemberListJoinStmt * sql . Stmt
var GetMemberStmt * sql . Stmt
var AttachForumStmt * sql . Stmt
var UnattachForumStmt * sql . Stmt
var AddMemberStmt * sql . Stmt
// Guild is a struct representing a guild
type Guild struct {
ID int
Link string
Name string
Desc string
Active bool
Privacy int /* 0: Public, 1: Protected, 2: Private */
// Who should be able to accept applications and create invites? Mods+ or just admins? Mods is a good start, we can ponder over whether we should make this more flexible in the future.
Joinable int /* 0: Private, 1: Anyone can join, 2: Applications, 3: Invite-only */
MemberCount int
Owner int
Backdrop string
CreatedAt string
LastUpdateTime string
MainForumID int
2019-04-19 06:36:26 +00:00
MainForum * c . Forum
Forums [ ] * c . Forum
ExtData c . ExtData
2017-11-10 03:33:11 +00:00
}
type Page struct {
2018-11-29 07:27:17 +00:00
Title string
2019-04-19 06:36:26 +00:00
Header * c . Header
ItemList [ ] * c . TopicsRow
Forum * c . Forum
2018-11-29 07:27:17 +00:00
Guild * Guild
Page int
LastPage int
2017-11-10 03:33:11 +00:00
}
// ListPage is a page struct for constructing a list of every guild
type ListPage struct {
2018-11-29 07:27:17 +00:00
Title string
2019-04-19 06:36:26 +00:00
Header * c . Header
2018-11-29 07:27:17 +00:00
GuildList [ ] * Guild
2017-11-10 03:33:11 +00:00
}
type MemberListPage struct {
2018-11-29 07:27:17 +00:00
Title string
2019-04-19 06:36:26 +00:00
Header * c . Header
2018-11-29 07:27:17 +00:00
ItemList [ ] Member
Guild * Guild
Page int
LastPage int
2017-11-10 03:33:11 +00:00
}
// Member is a struct representing a specific member of a guild, not to be confused with the global User struct.
type Member struct {
Link string
Rank int /* 0: Member. 1: Mod. 2: Admin. */
RankString string /* Member, Mod, Admin, Owner */
PostCount int
JoinedAt string
Offline bool // TODO: Need to track the online states of members when WebSockets are enabled
2019-04-19 06:36:26 +00:00
User c . User
2017-11-10 03:33:11 +00:00
}
2019-04-19 06:36:26 +00:00
func PrebuildTmplList ( user c . User , header * c . Header ) c . CTmpl {
2017-11-10 03:33:11 +00:00
var guildList = [ ] * Guild {
& Guild {
ID : 1 ,
Name : "lol" ,
2019-04-19 06:36:26 +00:00
Link : BuildGuildURL ( c . NameToSlug ( "lol" ) , 1 ) ,
2017-11-10 03:33:11 +00:00
Desc : "A group for people who like to laugh" ,
Active : true ,
MemberCount : 1 ,
Owner : 1 ,
CreatedAt : "date" ,
LastUpdateTime : "date" ,
MainForumID : 1 ,
2019-04-19 06:36:26 +00:00
MainForum : c . Forums . DirtyGet ( 1 ) ,
Forums : [ ] * c . Forum { c . Forums . DirtyGet ( 1 ) } ,
2017-11-10 03:33:11 +00:00
} ,
}
2018-04-22 12:33:56 +00:00
listPage := ListPage { "Guild List" , user , header , guildList }
2019-04-19 06:36:26 +00:00
return c . CTmpl { "guilds_guild_list" , "guilds_guild_list.html" , " templates / ", " guilds . ListPage ", listPage, []string{" . / extend / guilds / lib " } }
2017-11-10 03:33:11 +00:00
}
// TODO: Do this properly via the widget system
2017-11-29 02:34:02 +00:00
// TODO: REWRITE THIS
2019-04-19 06:36:26 +00:00
func CommonAreaWidgets ( header * c . Header ) {
2017-11-10 03:33:11 +00:00
// TODO: Hot Groups? Featured Groups? Official Groups?
var b bytes . Buffer
2019-04-19 06:36:26 +00:00
var menu = c . WidgetMenu { "Guilds" , [ ] c . WidgetMenuItem {
c . WidgetMenuItem { "Create Guild" , "/guild/create/" , false } ,
2017-11-10 03:33:11 +00:00
} }
2019-02-10 05:52:26 +00:00
err := header . Theme . RunTmpl ( "widget_menu" , pi , w )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
c . LogError ( err )
2017-11-10 03:33:11 +00:00
return
}
2018-04-22 12:33:56 +00:00
if header . Theme . HasDock ( "leftSidebar" ) {
header . Widgets . LeftSidebar = template . HTML ( string ( b . Bytes ( ) ) )
} else if header . Theme . HasDock ( "rightSidebar" ) {
header . Widgets . RightSidebar = template . HTML ( string ( b . Bytes ( ) ) )
2017-11-10 03:33:11 +00:00
}
}
// TODO: Do this properly via the widget system
// TODO: Make a better more customisable group widget system
2019-04-19 06:36:26 +00:00
func GuildWidgets ( header * c . Header , guildItem * Guild ) ( success bool ) {
2017-11-10 03:33:11 +00:00
return false // Disabled until the next commit
/ * var b bytes . Buffer
var menu WidgetMenu = WidgetMenu { "Guild Options" , [ ] WidgetMenuItem {
WidgetMenuItem { "Join" , "/guild/join/" + strconv . Itoa ( guildItem . ID ) , false } ,
WidgetMenuItem { "Members" , "/guild/members/" + strconv . Itoa ( guildItem . ID ) , false } ,
} }
err := templates . ExecuteTemplate ( & b , "widget_menu.html" , menu )
if err != nil {
2019-04-19 06:36:26 +00:00
c . LogError ( err )
2017-11-10 03:33:11 +00:00
return false
}
2018-04-22 12:33:56 +00:00
if themes [ header . Theme . Name ] . Sidebars == "left" {
header . Widgets . LeftSidebar = template . HTML ( string ( b . Bytes ( ) ) )
} else if themes [ header . Theme . Name ] . Sidebars == "right" || themes [ header . Theme . Name ] . Sidebars == "both" {
header . Widgets . RightSidebar = template . HTML ( string ( b . Bytes ( ) ) )
2017-11-10 03:33:11 +00:00
} else {
return false
}
return true * /
}
/ *
Custom Pages
* /
2019-04-19 06:36:26 +00:00
func RouteGuildList ( w http . ResponseWriter , r * http . Request , user c . User ) c . RouteError {
header , ferr := c . UserCheck ( w , r , & user )
2017-11-10 03:33:11 +00:00
if ferr != nil {
return ferr
}
2018-04-22 12:33:56 +00:00
CommonAreaWidgets ( header )
2017-11-10 03:33:11 +00:00
2017-11-11 04:06:16 +00:00
rows , err := ListStmt . Query ( )
2019-04-19 06:36:26 +00:00
if err != nil && err != c . ErrNoRows {
return c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
defer rows . Close ( )
var guildList [ ] * Guild
for rows . Next ( ) {
guildItem := & Guild { ID : 0 }
err := rows . Scan ( & guildItem . ID , & guildItem . Name , & guildItem . Desc , & guildItem . Active , & guildItem . Privacy , & guildItem . Joinable , & guildItem . Owner , & guildItem . MemberCount , & guildItem . CreatedAt , & guildItem . LastUpdateTime )
if err != nil {
2019-04-19 06:36:26 +00:00
return c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
2019-04-19 06:36:26 +00:00
guildItem . Link = BuildGuildURL ( c . NameToSlug ( guildItem . Name ) , guildItem . ID )
2017-11-10 03:33:11 +00:00
guildList = append ( guildList , guildItem )
}
err = rows . Err ( )
if err != nil {
2019-04-19 06:36:26 +00:00
return c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
2018-04-22 12:33:56 +00:00
pi := ListPage { "Guild List" , user , header , guildList }
2019-04-19 09:34:16 +00:00
return routes . RenderTemplate ( "guilds_guild_list" , w , r , header , pi )
2017-11-10 03:33:11 +00:00
}
2019-04-19 06:36:26 +00:00
func MiddleViewGuild ( w http . ResponseWriter , r * http . Request , user c . User ) c . RouteError {
2018-11-12 09:23:36 +00:00
_ , guildID , err := routes . ParseSEOURL ( r . URL . Path [ len ( "/guild/" ) : ] )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
return c . PreError ( "Not a valid guild ID" , w , r )
2017-11-10 03:33:11 +00:00
}
2017-11-23 05:37:08 +00:00
guildItem , err := Gstore . Get ( guildID )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
return c . LocalError ( "Bad guild" , w , r , user )
2017-11-10 03:33:11 +00:00
}
2018-04-22 12:33:56 +00:00
// TODO: Build and pass header
2017-11-10 03:33:11 +00:00
if ! guildItem . Active {
2019-04-19 06:36:26 +00:00
return c . NotFound ( w , r , nil )
2017-11-10 03:33:11 +00:00
}
2017-11-11 04:06:16 +00:00
return nil
// TODO: Re-implement this
2017-11-10 03:33:11 +00:00
// Re-route the request to routeForums
2017-11-11 04:06:16 +00:00
//var ctx = context.WithValue(r.Context(), "guilds_current_guild", guildItem)
//return routeForum(w, r.WithContext(ctx), user, strconv.Itoa(guildItem.MainForumID))
2017-11-10 03:33:11 +00:00
}
2019-04-19 06:36:26 +00:00
func RouteCreateGuild ( w http . ResponseWriter , r * http . Request , user c . User ) c . RouteError {
header , ferr := c . UserCheck ( w , r , & user )
2017-11-10 03:33:11 +00:00
if ferr != nil {
return ferr
}
2018-06-06 00:21:22 +00:00
header . Title = "Create Guild"
2017-11-10 03:33:11 +00:00
// TODO: Add an approval queue mode for group creation
if ! user . Loggedin || ! user . PluginPerms [ "CreateGuild" ] {
2019-04-19 06:36:26 +00:00
return c . NoPermissions ( w , r , user )
2017-11-10 03:33:11 +00:00
}
2018-04-22 12:33:56 +00:00
CommonAreaWidgets ( header )
2017-11-10 03:33:11 +00:00
2019-04-19 09:34:16 +00:00
return routes . RenderTemplate ( "guilds_create_guild" , w , r , header , c . Page { header , tList , nil } )
2017-11-10 03:33:11 +00:00
}
2019-04-19 06:36:26 +00:00
func RouteCreateGuildSubmit ( w http . ResponseWriter , r * http . Request , user c . User ) c . RouteError {
2017-11-10 03:33:11 +00:00
// TODO: Add an approval queue mode for group creation
if ! user . Loggedin || ! user . PluginPerms [ "CreateGuild" ] {
2019-04-19 06:36:26 +00:00
return c . NoPermissions ( w , r , user )
2017-11-10 03:33:11 +00:00
}
var guildActive = true
2019-04-19 06:36:26 +00:00
var guildName = c . SanitiseSingleLine ( r . PostFormValue ( "group_name" ) )
2017-12-30 05:47:46 +00:00
// TODO: Allow Markdown / BBCode / Limited HTML in the description?
2019-04-19 06:36:26 +00:00
var guildDesc = c . SanitiseBody ( r . PostFormValue ( "group_desc" ) )
2017-11-10 03:33:11 +00:00
var gprivacy = r . PostFormValue ( "group_privacy" )
var guildPrivacy int
switch gprivacy {
case "0" :
guildPrivacy = 0 // Public
case "1" :
guildPrivacy = 1 // Protected
case "2" :
guildPrivacy = 2 // private
default :
guildPrivacy = 0
}
// Create the backing forum
2019-04-19 06:36:26 +00:00
fid , err := c . Forums . Create ( guildName , "" , true , "" )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
return c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
2017-11-23 05:37:08 +00:00
gid , err := Gstore . Create ( guildName , guildDesc , guildActive , guildPrivacy , user . ID , fid )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
return c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
// Add the main backing forum to the forum list
2017-11-23 05:37:08 +00:00
err = AttachForum ( gid , fid )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
return c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
2017-11-23 05:37:08 +00:00
_ , err = AddMemberStmt . Exec ( gid , user . ID , 2 )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
return c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
2019-04-19 06:36:26 +00:00
http . Redirect ( w , r , BuildGuildURL ( c . NameToSlug ( guildName ) , gid ) , http . StatusSeeOther )
2017-11-10 03:33:11 +00:00
return nil
}
2019-04-19 06:36:26 +00:00
func RouteMemberList ( w http . ResponseWriter , r * http . Request , user c . User ) c . RouteError {
header , ferr := c . UserCheck ( w , r , & user )
2017-11-10 03:33:11 +00:00
if ferr != nil {
return ferr
}
2018-11-12 09:23:36 +00:00
_ , guildID , err := routes . ParseSEOURL ( r . URL . Path [ len ( "/guild/members/" ) : ] )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
return c . PreError ( "Not a valid group ID" , w , r )
2017-11-10 03:33:11 +00:00
}
2017-11-23 05:37:08 +00:00
guildItem , err := Gstore . Get ( guildID )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
return c . LocalError ( "Bad group" , w , r , user )
2017-11-10 03:33:11 +00:00
}
2019-04-19 06:36:26 +00:00
guildItem . Link = BuildGuildURL ( c . NameToSlug ( guildItem . Name ) , guildItem . ID )
2017-11-10 03:33:11 +00:00
2018-04-22 12:33:56 +00:00
GuildWidgets ( header , guildItem )
2017-11-10 03:33:11 +00:00
2017-11-11 04:06:16 +00:00
rows , err := MemberListJoinStmt . Query ( guildID )
2019-04-19 06:36:26 +00:00
if err != nil && err != c . ErrNoRows {
return c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
2017-11-11 04:06:16 +00:00
var guildMembers [ ] Member
2017-11-10 03:33:11 +00:00
for rows . Next ( ) {
2017-11-11 04:06:16 +00:00
guildMember := Member { PostCount : 0 }
2018-07-28 12:52:23 +00:00
err := rows . Scan ( & guildMember . User . ID , & guildMember . Rank , & guildMember . PostCount , & guildMember . JoinedAt , & guildMember . User . Name , & guildMember . User . RawAvatar )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
return c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
2019-04-19 06:36:26 +00:00
guildMember . Link = c . BuildProfileURL ( c . NameToSlug ( guildMember . User . Name ) , guildMember . User . ID )
guildMember . User . Avatar , guildMember . User . MicroAvatar = c . BuildAvatar ( guildMember . User . ID , guildMember . User . RawAvatar )
guildMember . JoinedAt , _ = c . RelativeTimeFromString ( guildMember . JoinedAt )
2017-11-10 03:33:11 +00:00
if guildItem . Owner == guildMember . User . ID {
guildMember . RankString = "Owner"
} else {
switch guildMember . Rank {
case 0 :
guildMember . RankString = "Member"
case 1 :
guildMember . RankString = "Mod"
case 2 :
guildMember . RankString = "Admin"
}
}
guildMembers = append ( guildMembers , guildMember )
}
err = rows . Err ( )
if err != nil {
2019-04-19 06:36:26 +00:00
return c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
rows . Close ( )
2018-04-22 12:33:56 +00:00
pi := MemberListPage { "Guild Member List" , user , header , guildMembers , guildItem , 0 , 0 }
2017-11-10 03:33:11 +00:00
// A plugin with plugins. Pluginception!
2019-04-19 06:36:26 +00:00
if c . RunPreRenderHook ( "pre_render_guilds_member_list" , w , r , & user , & pi ) {
2018-04-03 04:34:07 +00:00
return nil
}
2019-04-19 06:36:26 +00:00
err = c . RunThemeTemplate ( header . Theme . Name , "guilds_member_list" , pi , w )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
return c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
return nil
}
func AttachForum ( guildID int , fid int ) error {
2017-11-11 04:06:16 +00:00
_ , err := AttachForumStmt . Exec ( guildID , fid )
2017-11-10 03:33:11 +00:00
return err
}
func UnattachForum ( fid int ) error {
2017-11-11 04:06:16 +00:00
_ , err := AttachForumStmt . Exec ( fid )
2017-11-10 03:33:11 +00:00
return err
}
func BuildGuildURL ( slug string , id int ) string {
2019-04-19 06:36:26 +00:00
if slug == "" || ! c . Config . BuildSlugs {
2018-04-03 04:34:07 +00:00
return "/guild/" + strconv . Itoa ( id )
2017-11-10 03:33:11 +00:00
}
2018-04-03 04:34:07 +00:00
return "/guild/" + slug + "." + strconv . Itoa ( id )
2017-11-10 03:33:11 +00:00
}
/ *
Hooks
* /
// TODO: Prebuild this template
2019-04-19 06:36:26 +00:00
func PreRenderViewForum ( w http . ResponseWriter , r * http . Request , user * c . User , data interface { } ) ( halt bool ) {
pi := data . ( * c . ForumPage )
2017-11-11 04:06:16 +00:00
if pi . Header . ExtData . Items != nil {
if guildData , ok := pi . Header . ExtData . Items [ "guilds_current_group" ] ; ok {
2017-11-10 03:33:11 +00:00
guildItem := guildData . ( * Guild )
2018-11-29 07:27:17 +00:00
guildpi := Page { pi . Title , pi . Header , pi . ItemList , pi . Forum , guildItem , pi . Page , pi . LastPage }
2019-04-19 09:34:16 +00:00
err := routes . RenderTemplate ( "guilds_view_guild" , w , r , header , guildpi )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
c . LogError ( err )
2017-11-10 03:33:11 +00:00
return false
}
return true
}
}
return false
}
func TrowAssign ( args ... interface { } ) interface { } {
2019-04-19 06:36:26 +00:00
var forum = args [ 1 ] . ( * c . Forum )
2017-11-10 03:33:11 +00:00
if forum . ParentType == "guild" {
2019-04-19 06:36:26 +00:00
var topicItem = args [ 0 ] . ( * c . TopicsRow )
topicItem . ForumLink = "/guild/" + strings . TrimPrefix ( topicItem . ForumLink , c . GetForumURLPrefix ( ) )
2017-11-10 03:33:11 +00:00
}
return nil
}
// TODO: It would be nice, if you could select one of the boards in the group from that drop-down rather than just the one you got linked from
func TopicCreatePreLoop ( args ... interface { } ) interface { } {
var fid = args [ 2 ] . ( int )
2019-04-19 06:36:26 +00:00
if c . Forums . DirtyGet ( fid ) . ParentType == "guild" {
2017-11-10 03:33:11 +00:00
var strictmode = args [ 5 ] . ( * bool )
* strictmode = true
}
return nil
}
// TODO: Add privacy options
// TODO: Add support for multiple boards and add per-board simplified permissions
// TODO: Take isJs into account for routes which expect JSON responses
2019-04-19 06:36:26 +00:00
func ForumCheck ( args ... interface { } ) ( skip bool , rerr c . RouteError ) {
2017-11-10 03:33:11 +00:00
var r = args [ 1 ] . ( * http . Request )
var fid = args [ 3 ] . ( * int )
2019-04-19 06:36:26 +00:00
var forum = c . Forums . DirtyGet ( * fid )
2017-11-10 03:33:11 +00:00
if forum . ParentType == "guild" {
var err error
var w = args [ 0 ] . ( http . ResponseWriter )
guildItem , ok := r . Context ( ) . Value ( "guilds_current_group" ) . ( * Guild )
if ! ok {
2017-11-23 05:37:08 +00:00
guildItem , err = Gstore . Get ( forum . ParentID )
2017-11-10 03:33:11 +00:00
if err != nil {
2019-04-19 06:36:26 +00:00
return true , c . InternalError ( errors . New ( "Unable to find the parent group for a forum" ) , w , r )
2017-11-10 03:33:11 +00:00
}
if ! guildItem . Active {
2019-04-19 06:36:26 +00:00
return true , c . NotFound ( w , r , nil ) // TODO: Can we pull header out of args?
2017-11-10 03:33:11 +00:00
}
r = r . WithContext ( context . WithValue ( r . Context ( ) , "guilds_current_group" , guildItem ) )
}
2019-04-19 06:36:26 +00:00
var user = args [ 2 ] . ( * c . User )
2017-11-10 03:33:11 +00:00
var rank int
var posts int
var joinedAt string
// TODO: Group privacy settings. For now, groups are all globally visible
// Clear the default group permissions
// TODO: Do this more efficiently, doing it quick and dirty for now to get this out quickly
2019-04-19 06:36:26 +00:00
c . OverrideForumPerms ( & user . Perms , false )
2017-11-10 03:33:11 +00:00
user . Perms . ViewTopic = true
2017-11-11 04:06:16 +00:00
err = GetMemberStmt . QueryRow ( guildItem . ID , user . ID ) . Scan ( & rank , & posts , & joinedAt )
2019-04-19 06:36:26 +00:00
if err != nil && err != c . ErrNoRows {
return true , c . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
} else if err != nil {
// TODO: Should we let admins / guests into public groups?
2019-04-19 06:36:26 +00:00
return true , c . LocalError ( "You're not part of this group!" , w , r , * user )
2017-11-10 03:33:11 +00:00
}
// TODO: Implement bans properly by adding the Local Ban API in the next commit
// TODO: How does this even work? Refactor it along with the rest of this plugin!
if rank < 0 {
2019-04-19 06:36:26 +00:00
return true , c . LocalError ( "You've been banned from this group!" , w , r , * user )
2017-11-10 03:33:11 +00:00
}
// Basic permissions for members, more complicated permissions coming in the next commit!
if guildItem . Owner == user . ID {
2019-04-19 06:36:26 +00:00
c . OverrideForumPerms ( & user . Perms , true )
2017-11-10 03:33:11 +00:00
} else if rank == 0 {
user . Perms . LikeItem = true
user . Perms . CreateTopic = true
user . Perms . CreateReply = true
} else {
2019-04-19 06:36:26 +00:00
c . OverrideForumPerms ( & user . Perms , true )
2017-11-10 03:33:11 +00:00
}
return true , nil
}
return false , nil
}
// TODO: Override redirects? I don't think this is needed quite yet
func Widgets ( args ... interface { } ) interface { } {
var zone = args [ 0 ] . ( string )
2019-04-19 06:36:26 +00:00
var header = args [ 2 ] . ( * c . Header )
2017-11-10 03:33:11 +00:00
var request = args [ 3 ] . ( * http . Request )
if zone != "view_forum" {
return false
}
2019-04-19 06:36:26 +00:00
var forum = args [ 1 ] . ( * c . Forum )
2017-11-10 03:33:11 +00:00
if forum . ParentType == "guild" {
// This is why I hate using contexts, all the daisy chains and interface casts x.x
guildItem , ok := request . Context ( ) . Value ( "guilds_current_group" ) . ( * Guild )
if ! ok {
2019-04-19 06:36:26 +00:00
c . LogError ( errors . New ( "Unable to find a parent group in the context data" ) )
2017-11-10 03:33:11 +00:00
return false
}
2018-04-22 12:33:56 +00:00
if header . ExtData . Items == nil {
header . ExtData . Items = make ( map [ string ] interface { } )
2017-11-10 03:33:11 +00:00
}
2018-04-22 12:33:56 +00:00
header . ExtData . Items [ "guilds_current_group" ] = guildItem
2017-11-10 03:33:11 +00:00
2018-04-22 12:33:56 +00:00
return GuildWidgets ( header , guildItem )
2017-11-10 03:33:11 +00:00
}
return false
}