Files
wnsrc/lua/menu/ugcpublish.lua
lifestorm 9c918c46e5 Upload
2024-08-04 23:12:27 +03:00

326 lines
9.8 KiB
Lua

--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local PANEL = {}
function PANEL:Init()
self:SetSize( 700, 200 )
self:Center()
self:DockPadding( 10, 24 + 10, 10, 10 )
self:SetTitle( "#ugc_upload.frametitle" )
self:SetBackgroundBlur( true ) -- Indicate that the background elements won't be usable
--self:SetSizable( true )
self.AddonList = self:Add( "DListView" )
self.AddonList:Dock( RIGHT )
self.AddonList:SetWide( 200 )
self.AddonList:AddColumn( "#ugc_upload.existing" )
self.AddonList:DockMargin( 10, 0, 0, 0 )
self.AddonList:SetMultiSelect( false )
self.AddonList:SetMouseInputEnabled( false )
self.AddonList.OnRowSelected = function( s, ... ) self:OnRowSelected( ... ) end
self.AddonListLabel = self.AddonList:Add( "DLabel" )
self.AddonListLabel:Dock( FILL )
self.AddonListLabel:SetTextColor( color_black )
self.AddonListLabel:SetContentAlignment( 5 )
self.AddonListLabel:SetZPos( 100 )
self.AddonListLabel.Paint = function( s, w, h ) draw.RoundedBox( 0, 0, 0, w, h, Color( 0, 0, 0, 100 ) ) end -- TODO: Prolly should be hooked to skin
local topContainer = self:Add( "Panel" )
topContainer:Dock( TOP )
topContainer:SetTall( 200 )
self.Image = topContainer:Add( "DImage" )
self.Image:Dock( LEFT )
self.Image:SetWide( 200 )
self.Image:DockMargin( 0, 0, 5, 0 )
local titleLabel = topContainer:Add( "DLabel" )
titleLabel:Dock( TOP )
titleLabel:SetText( "#ugc_upload.title" )
self.Title = topContainer:Add( "DTextEntry" )
self.Title:Dock( TOP )
self.Title:SetUpdateOnType( true )
self.Title.OnTextChanged = function( s ) self:CheckInput() end
local descLabel = topContainer:Add( "DLabel" )
descLabel:Dock( TOP )
descLabel:SetText( "#ugc_upload.description" )
self.Description = topContainer:Add( "DTextEntry" )
self.Description:Dock( FILL )
self.Description:SetMultiline( true )
self.TagsLabel = self:Add( "DLabel" )
self.TagsLabel:Dock( TOP )
self.TagsLabel:SetText( "#ugc_upload.tags" )
self.Tags = self:Add( "Panel" )
self.Tags:Dock( TOP )
self.ChangeNotesLabel = self:Add( "DLabel" )
self.ChangeNotesLabel:Dock( TOP )
self.ChangeNotesLabel:DockMargin( 0, 5, 0, 0 )
self.ChangeNotesLabel:SetText( "#ugc_upload.changenotes" )
self.ChangeNotes = self:Add( "DTextEntry" )
self.ChangeNotes:Dock( TOP )
self.ChangeNotes:SetPlaceholderText( "ugc_upload.changenotes.help" )
self.ChangeNotes:SetVisible( false )
self.ChangeNotes:SetUpdateOnType( true )
self.ChangeNotes:SetMultiline( true )
self.ChangeNotes:SetTall( 80 )
self.Publish = self:Add( "DButton" )
self.Publish:Dock( TOP )
self.Publish:SetEnabled( false )
self.Publish:SetText( "#ugc_upload.publish" )
self.Publish:DockMargin( 0, 5, 0, 0 )
self.Publish.DoClick = function( s ) self:DoPublish() end
self.UpdateProgress = self:Add( "DLabel" )
self.UpdateProgress:SetText( "Publising your content, please wait..." )
self.UpdateProgress:SetTextColor( color_black )
self.UpdateProgress:SetContentAlignment( 5 )
self.UpdateProgress:SetZPos( 100 )
self.UpdateProgress:SetVisible( false )
self.UpdateProgress.Paint = function( s, w, h )
s:StretchToParent( 4, 4, 4, 4 )
draw.RoundedBox( 0, 0, 0, w, h, Color( 200, 200, 200, 255 ) ) -- TODO: Prolly should be hooked to skin
end
end
PANEL.TagsPerType = {
save = {
scenes = "#ugc_upload.tag_scenes_save",
courses = "#ugc_upload.tag_courses",
machines = "#ugc_upload.tag_machines",
buildings = "#ugc_upload.tag_buildings",
others = "#ugc_upload.tag_others"
},
dupe = {
posed = "#ugc_upload.tag_posed",
scenes = "#ugc_upload.tag_scenes",
vehicles = "#ugc_upload.tag_vehicles",
machines = "#ugc_upload.tag_machines",
buildings = "#ugc_upload.tag_buildings",
others = "#ugc_upload.tag_others"
}
}
function PANEL:FitContents()
-- Make this panel smaller, stuff below won't shrink it, only expand it
self:SetTall( 200 )
-- Set the window height to nicely fit everything, no extra space anywhere
self:InvalidateLayout( true )
self:SizeToChildren( false, true )
end
function PANEL:OnRowSelected( rowID, row )
-- Create new node, reset the fields
if ( !row.WorkshopData ) then
self.Publish:SetText( "#ugc_upload.publish" )
self.ChangeNotes:SetVisible( false )
self.ChangeNotesLabel:SetVisible( false )
self.Title:SetText( "" )
self.Description:SetText( "" )
for k, v in pairs( self.Tags:GetChildren() ) do v:SetChecked( false ) end -- SetChecked to not invoke OnChange
self:FitContents()
self:CheckInput()
return
end
local dat = row.WorkshopData
self.Title:SetText( dat.title )
self.Description:SetText( dat.description )
for k, v in pairs( self.Tags:GetChildren() ) do
if ( dat.tags:find( v:GetName() ) ) then v:SetValue( true ) break end
end
self.Publish:SetText( "#ugc_upload.update" )
self.ChangeNotes:SetVisible( true )
self.ChangeNotesLabel:SetVisible( true )
self:FitContents()
self:CheckInput()
end
function PANEL:Setup( ugcType, file, imageFile, handler )
self.ugcType = ugcType
self.ugcFile = file
self.ugcImage = imageFile
self.ugcHandler = handler
self.Image:SetImage( "../" .. self.ugcImage )
if ( self.TagsPerType[ self.ugcType ] ) then
for k, v in pairs( self.TagsPerType[ self.ugcType ] ) do
local rb = self.Tags:Add( "DCheckBoxLabel" )
rb:Dock( TOP )
rb:SetText( v )
rb:SetName( k )
rb:DockMargin( 4, 0, 0, 2 )
rb.OnChange = function( s, val )
self:CheckInput()
local num = 0
for id, pnl in pairs( s:GetParent():GetChildren() ) do
if ( pnl:GetChecked() ) then num = num + 1 end
if ( pnl == s or !val ) then continue end
pnl:SetValue( false ) -- Validate that only 1 is selected
end
if ( !val && num == 0 ) then s:SetValue( true ) end -- Don't allow to unselect the only 1 selected
end
Derma_Hook( rb.Button, "Paint", "Paint", "RadioButton" )
end
self.Tags:InvalidateChildren( false ) -- Update position of all the docked elements
self.Tags:SizeToChildren( false, true ) -- Set nice size for the tags container
else
self.TagsLabel:SetVisible( false )
self.Tags:SetVisible( false )
end
self:FitContents()
self:UpdateWorkshopItems()
end
function PANEL:UpdateWorkshopItems()
self.AddonListLabel:SetVisible( true )
self.AddonListLabel:SetText( "#ugc_upload.loading" )
self.AddonList:Clear()
self.AddonList:AddLine( "#ugc_upload.createnew" )
self.AddonList:SelectFirstItem()
steamworks.GetList( "mine", { self.ugcType }, 0, 9999, 0, "1", function( data )
for i, id in pairs( data.results ) do
steamworks.FileInfo( id, function( info )
local a = self.AddonList:AddLine( info.title )
a:SetTooltip( "#ugc_upload.rightclickopen" )
a.WorkshopID = id
a.WorkshopData = info
a.OnRightClick = function( s )
if ( !s.WorkshopID ) then return end
steamworks.ViewFile( s.WorkshopID )
end
self.AddonList:SetMouseInputEnabled( true )
self.AddonListLabel:SetVisible( false )
end )
end
if ( data.totalresults == 0 ) then
self.AddonListLabel:SetText( "#ugc_upload.nothingfound" )
end
end )
end
function PANEL:GetChosenTag()
for k, v in pairs( self.Tags:GetChildren() ) do
if ( v:GetChecked() ) then
return v:GetName()
end
end
end
function PANEL:CheckInput()
if ( self.TagsPerType[ self.ugcType ] && !self:GetChosenTag() ) then return self.Publish:SetEnabled( false ) end
if ( self.Title:GetText() == "" ) then return self.Publish:SetEnabled( false ) end
self.Publish:SetEnabled( true )
end
local errors = {}
errors[ "badhandle" ] = "Generic error while trying to create item."
errors[ "createid" ] = "Generic error while trying to create workshop item ID."
errors[ "badupdatehandle" ] = "Generic error while trying to update item."
errors[ "badsubmitupdatehandle" ] = "Could not submit update to Steam."
errors[ "cantupdate" ] = "Failed to upload workshop files to Steam."
errors[ "badwords" ] = "Please refrain from uploading spam, vulgar, sexual or offensive content to Steam Workshop."
function PANEL:DisplayError( err )
-- Unlock the UI and allow user to try again/make changes
self.UpdateProgress:SetVisible( false )
self:SetMouseInputEnabled( true )
if ( err == "termsofservice" ) then
err = "You must accept Steam Workshop Terms of Service before you can upload content!\nWould you like to open it right now?"
Derma_Query( err, "Error while publishing content!", "Yes", function()
gui.OpenURL( "http://steamcommunity.com/sharedfiles/workshoplegalagreement" )
end, "Nah" )
return
end
if ( errors[ err ] ) then err = errors[ err ] end
Derma_Message( err or "UNKNOWN ERROR", "Error while publishing content!", "OK" )
end
function PANEL:OnPublishFinished( wsid, err )
if ( !wsid ) then
self:DisplayError( err )
return
end
-- TODO: Show "View item"/"Close" buttons instead?
steamworks.ViewFile( wsid )
self:Remove()
end
function PANEL:DoPublish()
local ChosenTag = self:GetChosenTag()
if ( self.TagsPerType[ self.ugcType ] && ChosenTag == nil ) then
self:DisplayError( "You must choose a tag!")
return
end
if ( self.Title:GetText() == "" ) then
self:DisplayError( "You must provide a title!" )
return
end
local workshopUpdateID = nil
local updateButtonID, updateButton = self.AddonList:GetSelectedLine()
if ( IsValid( updateButton ) ) then
workshopUpdateID = updateButton.WorkshopID
end
-- Lock down the UI
self.UpdateProgress:SetVisible( true )
self:SetMouseInputEnabled( false )
-- TODO: Display update progress?
-- TODO: Confirmation dialog?
-- Start the process
local err = self.ugcHandler:FinishPublish( self.ugcFile, self.ugcImage, self.Title:GetText(), self.Description:GetText(), ChosenTag, {
WorkshopID = workshopUpdateID,
ChangeNotes = self.ChangeNotes:GetText(),
Callback = function( wsid, erro ) self:OnPublishFinished( wsid, erro ) end
} )
if ( err ) then self:DisplayError( err ) end
end
vgui.Register( "UGCPublishWindow", PANEL, "DFrame" )