2017-11-10 03:33:11 +00:00
package guilds
import (
"bytes"
"context"
"database/sql"
"errors"
"html/template"
"net/http"
"strconv"
"strings"
"../../../common"
)
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
MainForum * common . Forum
Forums [ ] * common . Forum
2017-11-11 04:06:16 +00:00
ExtData common . ExtData
2017-11-10 03:33:11 +00:00
}
type Page struct {
Title string
2017-11-11 04:06:16 +00:00
CurrentUser common . User
2018-04-22 12:33:56 +00:00
Header * common . Header
2017-11-11 04:06:16 +00:00
ItemList [ ] * common . TopicsRow
Forum * common . Forum
2017-11-10 03:33:11 +00:00
Guild * Guild
Page int
LastPage int
}
// ListPage is a page struct for constructing a list of every guild
type ListPage struct {
Title string
2017-11-11 04:06:16 +00:00
CurrentUser common . User
2018-04-22 12:33:56 +00:00
Header * common . Header
2017-11-10 03:33:11 +00:00
GuildList [ ] * Guild
}
type MemberListPage struct {
Title string
2017-11-11 04:06:16 +00:00
CurrentUser common . User
2018-04-22 12:33:56 +00:00
Header * common . Header
2017-11-11 04:06:16 +00:00
ItemList [ ] Member
2017-11-10 03:33:11 +00:00
Guild * Guild
Page int
LastPage int
}
// 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
2017-11-11 04:06:16 +00:00
User common . User
2017-11-10 03:33:11 +00:00
}
2018-04-22 12:33:56 +00:00
func PrebuildTmplList ( user common . User , header * common . Header ) common . CTmpl {
2017-11-10 03:33:11 +00:00
var guildList = [ ] * Guild {
& Guild {
ID : 1 ,
Name : "lol" ,
2017-11-11 04:06:16 +00:00
Link : BuildGuildURL ( common . 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 ,
2017-11-23 05:37:08 +00:00
MainForum : common . Forums . DirtyGet ( 1 ) ,
Forums : [ ] * common . Forum { common . 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 }
2017-11-11 06:33:08 +00:00
return common . 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
2018-04-22 12:33:56 +00:00
func CommonAreaWidgets ( header * common . Header ) {
2017-11-10 03:33:11 +00:00
// TODO: Hot Groups? Featured Groups? Official Groups?
var b bytes . Buffer
2017-11-11 04:06:16 +00:00
var menu = common . WidgetMenu { "Guilds" , [ ] common . WidgetMenuItem {
common . WidgetMenuItem { "Create Guild" , "/guild/create/" , false } ,
2017-11-10 03:33:11 +00:00
} }
2017-11-11 04:06:16 +00:00
err := common . Templates . ExecuteTemplate ( & b , "widget_menu.html" , menu )
2017-11-10 03:33:11 +00:00
if err != nil {
2017-11-11 04:06:16 +00:00
common . 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
2018-04-22 12:33:56 +00:00
func GuildWidgets ( header * common . 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 {
2017-11-11 04:06:16 +00:00
common . 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
* /
2017-11-11 04:06:16 +00:00
func RouteGuildList ( w http . ResponseWriter , r * http . Request , user common . User ) common . RouteError {
2018-04-22 12:33:56 +00:00
header , ferr := common . 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 ( )
if err != nil && err != common . ErrNoRows {
return common . 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 {
2017-11-11 04:06:16 +00:00
return common . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
2017-11-11 04:06:16 +00:00
guildItem . Link = BuildGuildURL ( common . NameToSlug ( guildItem . Name ) , guildItem . ID )
2017-11-10 03:33:11 +00:00
guildList = append ( guildList , guildItem )
}
err = rows . Err ( )
if err != nil {
2017-11-11 04:06:16 +00:00
return common . 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 }
err = common . RunThemeTemplate ( header . Theme . Name , "guilds_guild_list" , pi , w )
2017-11-10 03:33:11 +00:00
if err != nil {
2017-11-11 04:06:16 +00:00
return common . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
return nil
}
2017-11-11 04:06:16 +00:00
func MiddleViewGuild ( w http . ResponseWriter , r * http . Request , user common . User ) common . RouteError {
2017-11-10 03:33:11 +00:00
// SEO URLs...
halves := strings . Split ( r . URL . Path [ len ( "/guild/" ) : ] , "." )
if len ( halves ) < 2 {
halves = append ( halves , halves [ 0 ] )
}
guildID , err := strconv . Atoi ( halves [ 1 ] )
if err != nil {
2017-11-11 04:06:16 +00:00
return common . 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 {
2017-11-11 04:06:16 +00:00
return common . 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 {
2018-02-19 04:26:01 +00:00
return common . 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
}
2017-11-11 04:06:16 +00:00
func RouteCreateGuild ( w http . ResponseWriter , r * http . Request , user common . User ) common . RouteError {
2018-04-22 12:33:56 +00:00
header , ferr := common . 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" ] {
2017-11-11 04:06:16 +00:00
return common . 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
2018-06-06 00:21:22 +00:00
pi := common . Page { header , tList , nil }
2017-11-11 04:06:16 +00:00
err := common . Templates . ExecuteTemplate ( w , "guilds_create_guild.html" , pi )
2017-11-10 03:33:11 +00:00
if err != nil {
2017-11-11 04:06:16 +00:00
return common . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
return nil
}
2017-11-11 04:06:16 +00:00
func RouteCreateGuildSubmit ( w http . ResponseWriter , r * http . Request , user common . User ) common . RouteError {
2017-11-10 03:33:11 +00:00
// TODO: Add an approval queue mode for group creation
if ! user . Loggedin || ! user . PluginPerms [ "CreateGuild" ] {
2017-11-11 04:06:16 +00:00
return common . NoPermissions ( w , r , user )
2017-11-10 03:33:11 +00:00
}
var guildActive = true
2018-05-31 06:51:31 +00:00
var guildName = common . SanitiseSingleLine ( r . PostFormValue ( "group_name" ) )
2017-12-30 05:47:46 +00:00
// TODO: Allow Markdown / BBCode / Limited HTML in the description?
2018-05-31 06:51:31 +00:00
var guildDesc = common . 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
2017-11-23 05:37:08 +00:00
fid , err := common . Forums . Create ( guildName , "" , true , "" )
2017-11-10 03:33:11 +00:00
if err != nil {
2017-11-11 04:06:16 +00:00
return common . 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 {
2017-11-11 04:06:16 +00:00
return common . 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 {
2017-11-11 04:06:16 +00:00
return common . 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 {
2017-11-11 04:06:16 +00:00
return common . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
2017-11-23 05:37:08 +00:00
http . Redirect ( w , r , BuildGuildURL ( common . NameToSlug ( guildName ) , gid ) , http . StatusSeeOther )
2017-11-10 03:33:11 +00:00
return nil
}
2017-11-11 04:06:16 +00:00
func RouteMemberList ( w http . ResponseWriter , r * http . Request , user common . User ) common . RouteError {
2018-04-22 12:33:56 +00:00
header , ferr := common . UserCheck ( w , r , & user )
2017-11-10 03:33:11 +00:00
if ferr != nil {
return ferr
}
// SEO URLs...
halves := strings . Split ( r . URL . Path [ len ( "/guild/members/" ) : ] , "." )
if len ( halves ) < 2 {
halves = append ( halves , halves [ 0 ] )
}
guildID , err := strconv . Atoi ( halves [ 1 ] )
if err != nil {
2017-11-11 04:06:16 +00:00
return common . 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 {
2017-11-11 04:06:16 +00:00
return common . LocalError ( "Bad group" , w , r , user )
2017-11-10 03:33:11 +00:00
}
2017-11-11 04:06:16 +00:00
guildItem . Link = BuildGuildURL ( common . 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 )
if err != nil && err != common . ErrNoRows {
return common . 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 {
2017-11-11 04:06:16 +00:00
return common . InternalError ( err , w , r )
2017-11-10 03:33:11 +00:00
}
2017-11-11 04:06:16 +00:00
guildMember . Link = common . BuildProfileURL ( common . NameToSlug ( guildMember . User . Name ) , guildMember . User . ID )
2018-07-28 12:52:23 +00:00
guildMember . User . Avatar , guildMember . User . MicroAvatar = common . BuildAvatar ( guildMember . User . ID , guildMember . User . RawAvatar )
2017-11-11 04:06:16 +00:00
guildMember . JoinedAt , _ = common . 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 {
2017-11-11 04:06:16 +00:00
return common . 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!
2018-02-19 04:26:01 +00:00
if common . RunPreRenderHook ( "pre_render_guilds_member_list" , w , r , & user , & pi ) {
2018-04-03 04:34:07 +00:00
return nil
}
2018-04-22 12:33:56 +00:00
err = common . RunThemeTemplate ( header . Theme . Name , "guilds_member_list" , pi , w )
2017-11-10 03:33:11 +00:00
if err != nil {
2017-11-11 04:06:16 +00:00
return common . 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 {
2018-04-03 04:34:07 +00:00
if slug == "" || ! common . Config . BuildSlugs {
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
2017-11-11 04:06:16 +00:00
func PreRenderViewForum ( w http . ResponseWriter , r * http . Request , user * common . User , data interface { } ) ( halt bool ) {
pi := data . ( * common . ForumPage )
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 )
2017-11-11 04:06:16 +00:00
guildpi := Page { pi . Title , pi . CurrentUser , pi . Header , pi . ItemList , pi . Forum , guildItem , pi . Page , pi . LastPage }
err := common . Templates . ExecuteTemplate ( w , "guilds_view_guild.html" , guildpi )
2017-11-10 03:33:11 +00:00
if err != nil {
2017-11-11 04:06:16 +00:00
common . LogError ( err )
2017-11-10 03:33:11 +00:00
return false
}
return true
}
}
return false
}
func TrowAssign ( args ... interface { } ) interface { } {
2017-11-11 04:06:16 +00:00
var forum = args [ 1 ] . ( * common . Forum )
2017-11-10 03:33:11 +00:00
if forum . ParentType == "guild" {
2017-11-11 04:06:16 +00:00
var topicItem = args [ 0 ] . ( * common . TopicsRow )
topicItem . ForumLink = "/guild/" + strings . TrimPrefix ( topicItem . ForumLink , common . 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 )
2017-11-23 05:37:08 +00:00
if common . 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
2017-11-11 04:06:16 +00:00
func ForumCheck ( args ... interface { } ) ( skip bool , rerr common . RouteError ) {
2017-11-10 03:33:11 +00:00
var r = args [ 1 ] . ( * http . Request )
var fid = args [ 3 ] . ( * int )
2017-11-23 05:37:08 +00:00
var forum = common . 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 {
2017-11-11 04:06:16 +00:00
return true , common . 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 {
2018-04-22 12:33:56 +00:00
return true , common . 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 ) )
}
2017-11-11 04:06:16 +00:00
var user = args [ 2 ] . ( * common . 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
2017-11-11 04:06:16 +00:00
common . 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 )
if err != nil && err != common . ErrNoRows {
return true , common . 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?
2017-11-11 04:06:16 +00:00
return true , common . 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 {
2017-11-11 04:06:16 +00:00
return true , common . 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 {
2017-11-11 04:06:16 +00:00
common . 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 {
2017-11-11 04:06:16 +00:00
common . 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 )
2018-04-22 12:33:56 +00:00
var header = args [ 2 ] . ( * common . Header )
2017-11-10 03:33:11 +00:00
var request = args [ 3 ] . ( * http . Request )
if zone != "view_forum" {
return false
}
2017-11-11 04:06:16 +00:00
var forum = args [ 1 ] . ( * common . 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 {
2017-11-11 04:06:16 +00:00
common . 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
}