@@ -282,10 +282,10 @@ function create_window(id, prop = new WindowProperties()){
282282 if ( prop . remove_existing ) {
283283 const windows = document . getElementsByClassName ( 'floating_window' ) ;
284284 for ( let i = 0 ; i < windows . length ; i ++ ) {
285- windows [ i ] . style . display = 'none' ;
286285 while ( windows [ i ] . firstChild ) {
287286 windows [ i ] . removeChild ( windows [ i ] . firstChild ) ;
288287 }
288+ windows [ i ] . remove ( ) ;
289289 }
290290 }
291291 // remove existing with same id always
@@ -306,7 +306,12 @@ function create_window(id, prop = new WindowProperties()){
306306 prop . function_on_close ( ) ;
307307 return ;
308308 }
309- hide_all_windows ( ) ;
309+ //hide_all_windows();
310+ window . remove ( ) ;
311+ const windows = document . getElementsByClassName ( 'floating_window' ) ;
312+ if ( windows . length === 0 ) {
313+ hide_all_windows ( ) ;
314+ }
310315 }
311316 }
312317 }
@@ -317,7 +322,12 @@ function create_window(id, prop = new WindowProperties()){
317322 prop . function_on_close ( ) ;
318323 return ;
319324 }
320- hide_all_windows ( ) ;
325+ //hide_all_windows();
326+ window . remove ( ) ;
327+ const windows = document . getElementsByClassName ( 'floating_window' ) ;
328+ if ( windows . length === 0 ) {
329+ hide_all_windows ( ) ;
330+ }
321331 }
322332 }
323333 }
@@ -365,7 +375,11 @@ function create_window(id, prop = new WindowProperties()){
365375 prop . function_on_close ( ) ;
366376 return ;
367377 }
368- hide_all_windows ( ) ;
378+ window . remove ( ) ;
379+ const windows = document . getElementsByClassName ( 'floating_window' ) ;
380+ if ( windows . length === 0 ) {
381+ hide_all_windows ( ) ;
382+ }
369383 }
370384
371385 window . appendChild ( close ) ;
@@ -5210,11 +5224,288 @@ const generate_stars = (n, w) => {
52105224 }
52115225}
52125226
5213- function show_forum_index ( ) {
5227+ function get_posts ( topic_id , start_index = 0 , end_index = - 1 ) {
5228+ if ( topic_id == null || topic_id === '' ) {
5229+ return Promise . resolve ( [ ] ) ;
5230+ }
5231+
5232+ const url = '/api/get_posts' ;
5233+ const requestBody = JSON . stringify ( { topic_id : topic_id , start_index : start_index , end_index : end_index } ) ;
5234+ return fetch ( url , {
5235+ method : 'POST' ,
5236+ body : requestBody ,
5237+ headers : {
5238+ 'Content-Type' : 'application/json'
5239+ }
5240+ } )
5241+ . then ( response => response . text ( ) )
5242+ . then ( text => {
5243+ const json = JSON . parse ( text ) ;
5244+ if ( json . error ) {
5245+ console . error ( json . error ) ;
5246+ return Promise . resolve ( [ ] ) ;
5247+ }
5248+
5249+ return json . posts ;
5250+ } )
5251+ . catch ( error => {
5252+ console . error ( 'Error fetching posts:' , error ) ;
5253+ return Promise . resolve ( [ ] ) ;
5254+ } ) ;
5255+ }
5256+
5257+ function get_topics ( start_index = 0 , end_index = - 1 ) {
5258+ // fetch /api/get_topics
5259+ const url = '/api/get_topics' ;
5260+ const requestBody = JSON . stringify ( { start_index : start_index , end_index : end_index } ) ;
5261+ return fetch ( url , {
5262+ method : 'POST' ,
5263+ body : requestBody ,
5264+ headers : {
5265+ 'Content-Type' : 'application/json'
5266+ }
5267+ } )
5268+ . then ( response => response . text ( ) )
5269+ . then ( text => {
5270+ const json = JSON . parse ( text ) ;
5271+ if ( json . error ) {
5272+ console . error ( json . error ) ;
5273+ return [ ] ;
5274+ }
5275+
5276+ return json . topics ;
5277+ } )
5278+ . catch ( error => {
5279+ console . error ( 'Error fetching topics:' , error ) ;
5280+ return [ ] ;
5281+ } ) ;
5282+ }
5283+
5284+ function show_topic ( topic_id = '' , parent_topic_id = '' ) {
52145285 set_path ( '/topic' ) ;
52155286 hide_initial ( ) ;
52165287
5288+ if ( topic_id !== '' ) {
5289+ set_path ( '/topic/' + topic_id ) ;
5290+ }
5291+
52175292 const forum = create_window ( 'forum-window' ) ;
5293+
5294+ const topics_list = document . createElement ( 'div' ) ;
5295+ topics_list . className = 'forum-topics-list' ;
5296+ topics_list . id = 'forum-topics-list' ;
5297+
5298+ const topics = get_topics ( ) ;
5299+
5300+ // iterate over topics and create elements
5301+ topics . then ( topics => {
5302+ topics . forEach ( topic => {
5303+ if ( topic_id === '' || topic_id === null ) { // root topic then, we'll show all topics that are not referenced anywhere
5304+ let found = false ;
5305+ // in that case, the topic.identifier must not be found in any topic's topics array
5306+ topics . forEach ( t => {
5307+ if ( t . topics && t . topics . includes ( topic . identifier ) ) {
5308+ found = true ;
5309+ }
5310+ } ) ;
5311+
5312+ if ( found ) {
5313+ return ; // skip this topic if it is a subtopic
5314+ }
5315+ } else if ( parent_topic_id !== '' && parent_topic_id !== null ) {
5316+ // our topic_id must be found in the parent's topics array
5317+ if ( ! topic . topics || ! topic . topics . includes ( parent_topic_id ) ) {
5318+ return ; // skip this topic if it is not a subtopic of the given parent_topic_id
5319+ }
5320+ }
5321+ // same id = skip
5322+ if ( topic . identifier === topic_id ) {
5323+ return ;
5324+ }
5325+
5326+ const topic_div = document . createElement ( 'div' ) ;
5327+ topic_div . className = 'forum-topic' ;
5328+ topic_div . id = topic . id ;
5329+
5330+ const title = document . createElement ( 'strong' ) ;
5331+ title . innerHTML = topic . title ;
5332+ title . className = 'forum-topic-title' ;
5333+
5334+ const description = document . createElement ( 'p' ) ;
5335+ description . innerHTML = topic . description ;
5336+ description . className = 'forum-topic-description' ;
5337+ if ( description . innerHTML . length > 100 ) {
5338+ description . innerHTML = description . innerHTML . substring ( 0 , 100 ) + '...' ;
5339+ }
5340+
5341+ const author = document . createElement ( 'p' ) ;
5342+ author . innerHTML = `Posted by ${ topic . created_by } on ${ new Date ( topic . created_at ) . toLocaleDateString ( ) } ` ;
5343+ author . className = 'forum-topic-author' ;
5344+
5345+ topic_div . appendChild ( title ) ;
5346+ topic_div . appendChild ( author ) ;
5347+ topic_div . appendChild ( description ) ;
5348+
5349+ topic_div . onclick = ( ) => {
5350+ play_click ( ) ;
5351+ show_topic ( topic . identifier , topic_id ) ;
5352+ } ;
5353+
5354+ topics_list . appendChild ( topic_div ) ;
5355+ } ) ;
5356+ } ) ;
5357+
5358+ const posts_div = document . createElement ( 'div' ) ;
5359+ posts_div . className = 'forum-posts-list' ;
5360+ posts_div . id = 'forum-posts-list' ;
5361+
5362+ const posts = get_posts ( topic_id ) ;
5363+ posts . then ( posts => {
5364+ posts . forEach ( post => {
5365+ const post_div = document . createElement ( 'div' ) ;
5366+ post_div . className = 'forum-post' ;
5367+ post_div . id = post . id ;
5368+
5369+ const author = document . createElement ( 'strong' ) ;
5370+ author . innerHTML = post . created_by ;
5371+ author . className = 'forum-post-author' ;
5372+
5373+ const content = document . createElement ( 'p' ) ;
5374+ content . innerHTML = post . text ;
5375+ content . className = 'forum-post-content' ;
5376+
5377+ const date = document . createElement ( 'p' ) ;
5378+ date . innerHTML = new Date ( post . created_at ) . toLocaleDateString ( ) ;
5379+ date . className = 'forum-post-date' ;
5380+
5381+ post_div . appendChild ( author ) ;
5382+ post_div . appendChild ( date ) ;
5383+ post_div . appendChild ( content ) ;
5384+
5385+ posts_div . appendChild ( post_div ) ;
5386+ } ) ;
5387+ } ) ;
5388+
5389+ if ( is_logged_in ( ) && get_cookie ( 'user_type' ) === '1' ) {
5390+ const create_topic_button = document . createElement ( 'button' ) ;
5391+ create_topic_button . innerHTML = 'Create Topic' ;
5392+ create_topic_button . className = 'forum-create-topic-button' ;
5393+ create_topic_button . onclick = ( ) => {
5394+ play_click ( ) ;
5395+
5396+ const window = create_window ( 'create-topic-window' , { back_button : null , close_button : true , close_on_click_outside : true , close_on_escape : true } ) ;
5397+
5398+ const title_input = document . createElement ( 'input' ) ;
5399+ title_input . type = 'text' ;
5400+ title_input . name = 'title' ;
5401+ title_input . placeholder = 'Title' ;
5402+
5403+ const description_input = document . createElement ( 'textarea' ) ;
5404+ description_input . name = 'description' ;
5405+ description_input . placeholder = 'Description' ;
5406+
5407+ const button = document . createElement ( 'button' ) ;
5408+ button . innerHTML = 'Create Topic' ;
5409+ button . className = 'forum-create-topic-submit-button' ;
5410+ button . onclick = ( ) => {
5411+ if ( title_input . value && description_input . value ) {
5412+ play_click ( ) ;
5413+
5414+ const json = {
5415+ title : title_input . value ,
5416+ description : description_input . value ,
5417+ } ;
5418+
5419+ if ( parent_topic_id !== '' && parent_topic_id !== null ) {
5420+ json . parent_topics = [ parent_topic_id ] ;
5421+ }
5422+ fetch ( '/api/create_topic' , {
5423+ method : 'POST' ,
5424+ headers : {
5425+ 'Content-Type' : 'application/json'
5426+ } ,
5427+ body : JSON . stringify ( json )
5428+ } )
5429+ . then ( response => response . json ( ) )
5430+ . then ( data => {
5431+ if ( data . success ) {
5432+ show_topic ( parent_topic_id ) ;
5433+ } else {
5434+ alert ( 'Error creating topic: ' + data . error ) ;
5435+ }
5436+ } ) ;
5437+ }
5438+ }
5439+
5440+ window . appendChild ( title_input ) ;
5441+ window . appendChild ( description_input ) ;
5442+ window . appendChild ( button ) ;
5443+ } ;
5444+ forum . appendChild ( create_topic_button ) ;
5445+ }
5446+ if ( is_logged_in ( ) && topic_id !== '' && topic_id !== null ) {
5447+ const create_post_button = document . createElement ( 'button' ) ;
5448+ create_post_button . innerHTML = 'Create Post' ;
5449+ create_post_button . className = 'forum-create-post-button' ;
5450+ create_post_button . onclick = ( ) => {
5451+ play_click ( ) ;
5452+
5453+ const window = create_window ( 'create-post-window' , { back_button : null , close_button : true , close_on_click_outside : true , close_on_escape : true } ) ;
5454+
5455+ const title = document . createElement ( 'h2' ) ;
5456+ title . innerHTML = 'Create Post' ;
5457+ title . className = 'forum-create-post-title' ;
5458+
5459+ const title_input = document . createElement ( 'input' ) ;
5460+ title_input . type = 'text' ;
5461+ title_input . name = 'title' ;
5462+ title_input . placeholder = 'Title' ;
5463+ title_input . className = 'forum-create-post-title-input' ;
5464+
5465+ const content_input = document . createElement ( 'textarea' ) ;
5466+ content_input . name = 'content' ;
5467+ content_input . placeholder = 'Content' ;
5468+ content_input . className = 'forum-create-post-content-input' ;
5469+ content_input . style . height = '200px' ;
5470+ content_input . style . width = '80%' ;
5471+
5472+ const button = document . createElement ( 'button' ) ;
5473+ button . innerHTML = 'Create Post' ;
5474+ button . className = 'forum-create-post-submit-button' ;
5475+ button . onclick = ( ) => {
5476+ if ( content_input . value ) {
5477+ fetch ( '/api/create_post' , {
5478+ method : 'POST' ,
5479+ headers : {
5480+ 'Content-Type' : 'application/json'
5481+ } ,
5482+ body : JSON . stringify ( {
5483+ topic_id : topic_id ,
5484+ title : title_input . value ,
5485+ text : content_input . value ,
5486+ } )
5487+ } )
5488+ . then ( response => response . json ( ) )
5489+ . then ( data => {
5490+ if ( data . success ) {
5491+ show_topic ( topic_id ) ;
5492+ } else {
5493+ alert ( 'Error creating post: ' + data . error ) ;
5494+ }
5495+ } ) ;
5496+ }
5497+ }
5498+
5499+ window . appendChild ( title ) ;
5500+ window . appendChild ( title_input ) ;
5501+ window . appendChild ( content_input ) ;
5502+ window . appendChild ( button ) ;
5503+ } ;
5504+ forum . appendChild ( create_post_button ) ;
5505+ }
5506+
5507+ forum . appendChild ( topics_list ) ;
5508+ forum . appendChild ( posts_div ) ;
52185509}
52195510
52205511function show_credits ( ) {
@@ -5513,7 +5804,7 @@ function init_page() {
55135804 description : "Check out the Forwarder Factory forum." ,
55145805 background_color : "" ,
55155806 id : "forum-button" ,
5516- onclick : "play_click(); show_forum_index ()" ,
5807+ onclick : "play_click(); show_topic ()" ,
55175808 } ) )
55185809
55195810 if ( get_cookie ( "username" ) === null ) {
@@ -5643,7 +5934,7 @@ document.addEventListener('DOMContentLoaded', async () => {
56435934 if ( get_path ( ) === "/admin" && is_logged_in ( ) ) show_admin ( ) ;
56445935 if ( get_path ( ) === "/admin" && ! is_logged_in ( ) ) show_login ( ) ;
56455936 if ( get_path ( ) === "/logout" && is_logged_in ( ) ) show_logout ( ) ;
5646- if ( get_path ( ) === "/topic" ) show_forum_index ( ) ;
5937+ if ( get_path ( ) === "/topic" ) show_topic ( ) ;
56475938
56485939 if ( get_path ( ) . startsWith ( "/view/" ) ) {
56495940 const id = get_path ( ) . substring ( 6 ) ;
@@ -5657,6 +5948,10 @@ document.addEventListener('DOMContentLoaded', async () => {
56575948 const name = get_path ( ) . substring ( 9 ) ;
56585949 view_profile ( name ) ;
56595950 }
5951+ if ( get_path ( ) . startsWith ( "/topic/" ) ) {
5952+ const topic_id = get_path ( ) . substring ( 7 ) ;
5953+ show_topic ( topic_id ) ;
5954+ }
56605955
56615956 print_username ( username , display_name , profile_key ) ;
56625957} ) ;
0 commit comments