try ( destroyDialog RsNewsFeedRollout ) catch () global rsNewsFeedMgr rollout RsNewsFeedRollout "Rockstar News" ( dotNetControl tbNewsFeeds "System.Windows.Forms.TabControl" height:24 pos:[ 0, 0 ] dotNetControl wb "System.Windows.Forms.WebBrowser" width:800 height:550 pos:[ 0, 24 ] checkbox cbOnlyShowOnNewPosts "Only show on new posts" checked:( rsNewsFeedMgr.getOnlyShowOnNewPosts() ) offset:[ -8, 2 ] fn showNewsFeed feedIdx = ( -- This is custom to TiddlyWiki URL arguments. local args = "#tag:all readOnly:yes" local userTypeTag = rsNewsFeedMgr.getUserTag "nobody" if userTypeTag != undefined then ( args += " tag:" + userTypeTag ) wb.url = dotNetObject "System.Uri" ( rsNewsFeedMgr.newsFeeds[ feedIdx ].url + args ) ) fn populateNewFeeds = ( tbNewsFeeds.tabPages.clear() for newFeed in rsNewsFeedMgr.newsFeeds do ( tbNewsFeeds.tabPages.add newFeed.name ) ) on tbNewsFeeds Click do ( local tabIdx = tbNewsFeeds.SelectedIndex + 1 showNewsFeed tabIdx ) on RsNewsFeedRollout open do ( populateNewFeeds() showNewsFeed 1 ) on cbOnlyShowOnNewPosts changed state do ( rsNewsFeedMgr.setOnlyShowOnNewPosts state ) ) struct RsNewsFeed ( /* Structure for a news feed. */ name = undefined, url = undefined ) struct RsNewsFeedManager ( /* Manages the news feeds. */ public -- Array of RsNewsFeed objects, which is populated via the parsing of newsFeeds.xml newsFeeds = #(), -- When set to true, will force the news feed dialog to open. forceShow = false, private -- Ini settings local to the user only. iniNewsFeed = "NewsFeeds", iniLastSeen = "LastSeen", iniOnlyShowOnNewPosts = "OnlyShowOnNewPosts", iniFile = ( PathConfig.GetDir #temp ) + "\\newsFeeds.ini", onlyShowOnNewPosts = true, -- Stores the user type as the key, and their respective tag as the value. This hashtable gets populated -- via the newsFeeds.xml file. tags = dotNetObject "System.Collections.Hashtable", fn loadPreviousUserSettings = ( /* Retrieve the users previous settings. */ -- Setup ini file for the first time, or if it was previously deleted. if not ( doesFileExist this.iniFile ) then ( setIniSetting this.iniFile this.iniNewsFeed this.iniLastSeen "undefined" setIniSetting this.iniFile this.iniNewsFeed this.iniOnlyShowOnNewPosts "true" ) this.onlyShowOnNewPosts = ( getIniSetting this.iniFile this.iniNewsFeed this.iniOnlyShowOnNewPosts ) as BooleanClass ), fn loadFeeds = ( /* Parses newsFeeds.xml to determine what feeds the project would like to display. */ -- Sync to the latest feed files. gRsPerforce.sync ( RsConfigGetProjRootDir() + "docs/TechArt/NewsFeeds/..." ) -- Get the xml config file that lists which feeds to show. local newsFeedXml = RsConfigGetWildwestDir() + "etc/config/general/newsFeeds.xml" if ( doesFileExist newsFeedXml ) then ( local stream = dotNetObject "System.IO.StreamReader" newsFeedXml local doc = dotNetObject "System.Xml.XmlDocument" doc.load stream root = doc.documentElement -- Collect all news feeds. newsFeedNodes = ( root.SelectNodes ".//newsFeed" ) for idx = 0 to ( newsFeedNodes.count - 1 ) do ( local newsFeedNode = newsFeedNodes.item[ idx ] local newsFeed = RsNewsFeed() newsFeed.name = newsFeedNode.attributes.ItemOf[ 0 ].value newsFeed.url = RsConfigGetProjRootDir() + newsFeedNode.InnerText append this.newsFeeds newsFeed ) -- Collect all tags. tagNodes = ( root.SelectNodes ".//settings/tags/tag" ) for tagIdx = 0 to ( tagNodes.count - 1 ) do ( local tagNode = tagNodes.item[ tagIdx ] local userType = tagNode.attributes.ItemOf[ 0 ].value local tag = tagNode.InnerText this.tags.Add userType tag ) ) ), public fn getOnlyShowOnNewPosts = ( /* Get whether or not the dialog will be shown on new posts only. */ this.onlyShowOnNewPosts ), fn setOnlyShowOnNewPosts state = ( /* Set whether or not the news feed dialog will be shown on new posts only. */ this.onlyShowOnNewPosts = state setIniSetting this.iniFile this.iniNewsFeed this.iniOnlyShowOnNewPosts ( state as string ) ), fn getUserTag userType = ( /* Get the tag associated with the supplied user type. */ local tag = undefined if ( this.tags.Contains userType ) then ( tag = this.tags.Item[ userType ] ) tag ), fn show = ( /* Show the news feed dialog. */ this.loadFeeds() this.loadPreviousUserSettings() local showDialog = false local dateTime = dotNetClass "System.DateTime" -- Determine if any of the news feeds are newer than the last time the user saw them. If they are, -- then show the dialog. if this.onlyShowOnNewPosts == true then ( local lastSeen = getIniSetting this.iniFile this.iniNewsFeed this.iniLastSeen -- Hit this case if the ini file was first created. User has never seen it before, so we want to show it, and record the date and time. if lastSeen == "undefined" then ( setIniSetting this.iniFile this.iniNewsFeed this.iniLastSeen ( dateTime.Now.ToString() ) ) else ( for newsFeed in this.newsFeeds do ( local newsFeedHtml = dotNetObject "System.IO.FileInfo" newsFeed.url local lastSeenDateTime = dateTime.Parse lastSeen local newsFeedDateTime = newsFeedHtml.LastWriteTime local compare = dateTime.Compare lastSeenDateTime newsFeedDateTime -- The latest news html is newer than the last time the user saw it, so we need to display it. if compare < 0 then ( showDialog = true setIniSetting this.iniFile this.iniNewsFeed this.iniLastSeen ( dateTime.Now.ToString() ) ) ) ) ) else ( showDialog = true ) if this.forceShow == true then ( showDialog = true ) if showDialog == true then ( createDialog RsNewsFeedRollout width:800 height:600 ) ) ) rsNewsFeedMgr = RsNewsFeedManager() rsNewsFeedMgr.show()