· 8 years ago · Feb 23, 2018, 02:46 AM
1// ==UserScript==
2// @name ResetEra - Hide Forum Threads
3// @namespace ThreadFilter_Resetera
4// @description Hides threads on Resetera.com
5// @require http://code.jquery.com/jquery-latest.min.js
6// @require http://code.jquery.com/ui/1.11.2/jquery-ui.min.js
7// @include http*://*resetera.com/forums/*.*
8
9// @version 0.0.1
10// ==/UserScript==
11
12
13
14var sThreadTitle;
15currentVisibleThreads = [];
16nShownCount = 0;
17nOriginalPageCount = GetNextPage();
18nPageCount = nOriginalPageCount;
19nAdditionalThreadCount = 0;
20
21var isInMainForums = false;
22
23$(document).ready(function() {
24 CheckCloudSync();
25 CheckExpiredThreads();
26
27 CreateStyles();
28 CreateFilter();
29 CreateControlPanel();
30 CreateEventHandlers();
31
32 SetOptions();
33
34 UpdateHideLinks();
35
36 UpdateThreads();
37});
38
39function CreateStyles()
40{
41 $("body").append("<link rel='stylesheet' href='//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css'>");
42
43 if (localStorage.getItem("HideLinkStyle") != "HideShow")
44 $("body").append(GetRemoveStyle());
45}
46
47function CreateFilter()
48{
49 isInMainForums = $( "#forums" ).is( ".nodeList.sectionMain" );
50 if (isInMainForums )
51 {
52 $('.forumNodeInfo.primaryContent').parent().append("<select id='ThreadFilter'><option value='Unignored' selected='true'>Show Unignored Only</option><option value='Ignored'>Show Ignored Only</option><option value='All'>Show All</option></select> ");
53}else{
54 $('.titleBar').append("<select id='ThreadFilter'><option value='Unignored' selected='true'>Show Unignored Only</option><option value='Ignored'>Show Ignored Only</option><option value='All'>Show All</option></select> ");
55}
56
57
58}
59
60function GetRemoveStyle()
61{
62 var HideThreadStyle = 'margin-left: -3px; margin-top: -8px;';
63 var HideThreadStyle2 = 'padding-left:10px; margin-left:-25px; margin-top:-2px;';
64
65
66 RemoveStyle = '<style id="RemoveStyle">';
67 RemoveStyle += '.discussionListItem > .listBlock.main > a[id^="RemoveThread"]:before { content: "x"; font-size: 15pt;}';
68 RemoveStyle += '.discussionListItem > .listBlock.main > a[id^="RemoveThread"] { position: absolute !important; ' + (navigator.userAgent.search("Chrome") >= 0 ? HideThreadStyle : HideThreadStyle2) + ' font-size: 0pt; visibility: hidden !important;}';
69 RemoveStyle += '.discussionListItem > .listBlock.main:hover > a[id^="RemoveThread"] { visibility: visible !important; } ';
70
71 //RemoveStyle += '.discussionListItem > td > a[id^="RemoveUser"]:before { content: "x"; font-size: 15pt;} ';
72 //RemoveStyle += '.discussionListItem > td > a[id^="RemoveUser"] { position: absolute !important; padding-left:10px; margin-left:-25px; //margin-top:-2px; font-size: 0pt; visibility: hidden !important;} ';
73 //RemoveStyle += '.discussionListItem > td:hover > a[id^="RemoveUser"] { visibility: visible !important; } ';
74 RemoveStyle += '</style>';
75
76 return RemoveStyle;
77}
78
79function UpdateHideLinks()
80{
81 $("li[id*='thread-']").each(function( index,value ) { AddHideLink(this);});
82}
83
84function CreateEventHandlers()
85{
86 $('#ThreadFilter').change(function() { UpdateThreads(); UpdateHideLinks();});
87 $('#OpenFilterCP').click(OpenFilterCP);
88 $('#AddWordButton').click(AddToWordFilter);
89 $('#AddIgnoredUserButton').click(AddToIgnoredUserList);
90 $('input[name="HideLinkStyle"]').change(function () { localStorage.setItem('HideLinkStyle', this.value); RemoveHideLinks(); SaveLastUpdate();});
91 $('#SearchAdditional').change(function() { localStorage.setItem('SearchAdditional', this.checked); SaveLastUpdate();});
92 $('#CloudSync').change(function() { localStorage.setItem('CloudSync', this.checked); ShowCloudSyncOptions(this); });
93 $('#CloudSyncFrequency').change(function() { localStorage.setItem('CloudSyncFrequency', this.value); SaveLastUpdate(); });
94 $('#CloudSyncKey').change(function() {CloudKeyChanged(this.value);});
95 $('#GenerateCloudSyncKey').click(GenerateCloudSyncKey);
96 $('#ThreadExpiration').change(function() { localStorage.setItem('ThreadExpiration', this.checked); if (localStorage.getItem('ExpirationDays') == null) {localStorage.setItem('ExpirationDays',30); document.getElementById("ExpirationDays").value = localStorage.getItem("ExpirationDays");} $('#ThreadExpirationOptions').toggle(); SaveLastUpdate(); });
97 $('#ExpirationDays').change(function() {localStorage.setItem('ExpirationDays', this.value);});
98}
99
100function RemoveHideLinks()
101{
102 $("a[id*='RemoveThread']").remove();
103 $("a[id*='RemoveUser']").remove();
104
105 $("#RemoveStyle").remove();
106
107 if (localStorage.getItem("HideLinkStyle") != "HideShow")
108 $("body").append(GetRemoveStyle());
109}
110
111function SetOptions()
112{
113 document.getElementById("ThreadFilter").value = CheckThreadFilterValue(localStorage.getItem("ThreadFilter"));
114
115 if (localStorage.getItem("CloudSyncKey"))
116 document.getElementById("CloudSyncKey").value = localStorage.getItem("CloudSyncKey");
117
118 if (!localStorage.getItem("HideLinkStyle"))
119 localStorage.setItem("HideLinkStyle","X");
120
121 if (localStorage.getItem("ExpirationDays"))
122 document.getElementById("ExpirationDays").value = localStorage.getItem("ExpirationDays");
123
124 CheckSettingOption("SearchAdditional");
125 CheckSettingOption("CloudSync");
126 CheckSettingOption("HideLinkStyle");
127 CheckSettingOption("ThreadExpiration");
128
129 $('#ThreadExpirationOptions').css('display',$('#ThreadExpiration').prop('checked') ? 'block' : 'none');
130}
131
132function UpdateThreads()
133 {
134 nShownCount = 0;
135 $('#ThreadFilter').blur();
136 localStorage.setItem('ThreadFilter',document.getElementById("ThreadFilter").value);
137 currentVisibleThreads = [];
138
139 $("li[id*=thread-]").each(function(index)
140 {
141 var nThreadID = $(this).attr('id').replace('thread-','');
142 var sThreadTitle = $('a[href$="' + nThreadID + '/unread').text();
143
144 var MemberLink = $(this).children().find('a[href*="members/"]')[0].href.replace("https://www.resetera.com/members/","");
145 var sUserID = MemberLink.replace(/\//g, '').trim();
146
147 if (CheckThreadHidden(nThreadID,sThreadTitle,sUserID))
148 $(this).hide();
149 else
150 {
151 currentVisibleThreads.push(nThreadID);
152 nShownCount++;
153 $(this).show();
154 }
155 });
156
157 if (localStorage.getItem("SearchAdditional") == "true")
158 {
159 nPageCount = nOriginalPageCount;
160 GetAdditionalThreads();
161 }
162
163}
164
165
166function GetAdditionalThreads()
167{
168 if (nShownCount < 40 && nPageCount <= (parseInt(nOriginalPageCount) + 5))
169 {
170 console.log("getting additional info from \n" + window.location.href + "&order=desc&page=" + nPageCount);
171 var jqxhr = $.get(window.location.href + "page-" + nPageCount, ProcessAdditionalThread)
172 .done(function() {
173 nPageCount ++;
174 GetAdditionalThreads();
175 });
176 }
177}
178
179function ProcessAdditionalThread(data)
180{
181 var lastThread = $("li[id*='thread-']").last();
182
183 $(data).find("li[id*='thread-']").each(function(index, value)
184 {
185 var nThreadID = $(this).attr('id').replace('thread-','');
186 var sThreadTitle = $('a[href$="' + nThreadID + '/unread').text();
187
188 var MemberLink = $(this).children().find('a[href*="members/"]')[0].href.replace("https://www.resetera.com/members/","");
189 var sUserID = MemberLink.replace(/\//g, '').trim();
190
191 nAdditionalThreadCount = nAdditionalThreadCount + 1;
192
193 if (!CheckThreadHidden(nThreadID, sThreadTitle, sUserID) && nShownCount < 40 && $.inArray(nThreadID,currentVisibleThreads) == -1)
194 {
195 $(lastThread).after($(this).clone().wrap('<p>').html());
196
197 AddHideLink($("li[id*='thread-']" + nThreadID + "]"));
198 nShownCount++;
199 }
200
201 });
202}
203
204function CheckThreadFilterValue(sFilterValue)
205{
206 if (sFilterValue != "Unignored" && sFilterValue != "Ignored" && sFilterValue != "All")
207 sFilterValue = "Unignored";
208
209 return sFilterValue;
210}
211
212function IgnoreItem(event) {
213 var nCurrentID = event.data.param1;
214 var sList = event.data.param2;
215 var addItem = {};
216 addItem.ID = nCurrentID;
217 addItem.AddDate = new Date();
218
219 if (sList == "IgnoreList"){
220 //filter the title out using a selection with a given jQuery collection or element
221 var selector = $('a[href$="' + nCurrentID + '/unread');
222 var sThreadTitle = $(this).find(selector).text();
223 addItem.Title = sThreadTitle;
224 }
225 else if (sList == "IgnoredUserList")
226 //addItem.Username = $('a[href="member.php?u=' + nCurrentID + '"]').attr("title");
227 addItem.Username = $('a[href="members/' + nCurrentID + '"]').text();
228
229 CurrentList = GetListFromLocalStorage(sList);
230 containsObject(nCurrentID,CurrentList,addItem);
231
232 localStorage.setItem(sList, JSON.stringify(CurrentList));
233
234 if (event.data.param3)
235 event.data.param3();
236
237 AddHideLink(event.data.param4);
238
239 SaveLastUpdate();
240
241 CheckCloudUpdateNeeded();
242
243 return 0;
244}
245
246function AddHideLink(currentThread)
247{
248 IgnoreList = GetListFromLocalStorage('IgnoreList');
249 IgnoredUserList = GetListFromLocalStorage('IgnoredUserList');
250
251 nThreadID = $(currentThread).attr('id').replace('thread-','');
252
253 MemberLink = $(currentThread).children().find('a[href*="members/"]')[0];
254 nUserID = MemberLink.href.replace("https://www.resetera.com/members/",""); //might need to remove last character if '/' exists at end there
255 nUserID = nUserID.replace(/\//g, '').trim();
256
257 var bThreadIgnored = (containsObject(nThreadID,IgnoreList) == -1) ? false : true;
258 var bUserIgnored = (containsObject(nUserID,IgnoredUserList) == -1) ? false : true;
259 var sThreadFilterVal = $('#ThreadFilter').val();
260
261 if (sThreadFilterVal == 'Unignored')
262 {
263 ThreadIgnoreText = "Hide";
264 UserIgnoreText = "Remove";
265 }
266 else
267 {
268 ThreadIgnoreText = bThreadIgnored ? "Show" : "Hide";
269 UserIgnoreText = bUserIgnored ? "Restore" : "Remove";
270 }
271
272 if ($(currentThread).has("a[id*='RemoveThread" + nThreadID + "']").length == 0)
273 {
274 var RemoveUserLinks = ""//$('a[id*=RemoveUser' + nUserID + ']').toArray();
275
276 sUserIDReference = (RemoveUserLinks.length > 0) ? nUserID + RemoveUserLinks.length : nUserID;
277
278 //if (localStorage.getItem("HideLinkStyle") == "HideShow")
279 // $(MemberLink).after("<br /><a id='RemoveUser" + sUserIDReference + "'>" + UserIgnoreText + " User</a>");
280 // else
281 // $(MemberLink).before("<a id='RemoveUser" + sUserIDReference + "'>" + UserIgnoreText + " User</a>");
282
283 //$('#RemoveUser' + sUserIDReference).click({param1: nUserID, param2: 'IgnoredUserList', param3: UpdateThreads, param4: currentThread}, IgnoreItem);
284
285 var placeAfter = $('.listBlock.main');
286
287 $('<a></a>', {
288 id: "RemoveThread" + nThreadID,
289 text: ThreadIgnoreText
290 }).prependTo($(currentThread).find(placeAfter));
291
292 $('#RemoveThread' + nThreadID).click({param1: nThreadID, param2: 'IgnoreList', param3: UpdateThreads, param4: currentThread}, IgnoreItem);
293 }
294 else
295 {
296 $('#RemoveThread' + nThreadID).text(ThreadIgnoreText);
297 //$('a[id*=RemoveUser' + nUserID).text(UserIgnoreText + " User");
298 }
299}
300
301
302function CheckThreadHidden(nThreadID, sThreadTitle,sUserID)
303{
304 var sThreadFilterVal = $('#ThreadFilter').val();
305 var bWordFilterApplies = false;
306 var bUserFilterApplies = false;
307
308 IgnoreList = GetListFromLocalStorage('IgnoreList');
309 nThreadIndex = containsObject(nThreadID,IgnoreList);
310
311 var bThreadIgnored = (nThreadIndex == -1) ? false : true;
312
313 if ((bThreadIgnored && sThreadFilterVal == 'Unignored'))
314 {
315 return true;
316 }
317 else
318 {
319 bWordFilterApplies = WordFilterApplies(sThreadTitle);
320
321 if (bWordFilterApplies && sThreadFilterVal == 'Unignored')
322 {
323 return true;
324 }
325 else
326 {
327 bUserFilterApplies = containsObject(sUserID,GetListFromLocalStorage('IgnoredUserList')) != -1 ? true : false;
328
329 if (bUserFilterApplies && sThreadFilterVal == 'Unignored')
330 {
331 return true;
332 }
333 else if (!bThreadIgnored && !bWordFilterApplies && !bUserFilterApplies && sThreadFilterVal == 'Ignored')
334 {
335 return true;
336 }
337 }
338
339 }
340
341 return false;
342}
343
344function WordFilterApplies(sThreadTitle)
345{
346 CurrentArea = GetCurrentArea();
347
348 var bFilterApplies = false;
349 WordList = GetListFromLocalStorage('WordList');
350
351 jQuery.each(WordList,function (index)
352 {
353
354 if (this.Area == null || this.Area == 'All' || this.Area == CurrentArea)
355 {
356 if (this.Type == 'plaintext')
357 {
358 sFragments = this.Word.split('*');
359
360 bMatchesPattern = true;
361
362 jQuery.each(sFragments, function(index)
363 {
364 if (sThreadTitle.toLowerCase().indexOf(this.toLowerCase()) == -1)
365 {
366 bMatchesPattern = false;
367 }
368 });
369
370 if (bMatchesPattern === true)
371 {
372 bFilterApplies = true;
373 return 0;
374 }
375 }
376 else if (this.Type == 'regularexpression')
377 {
378 sRegExMatches = sThreadTitle.match(this.Word);
379
380 if (sRegExMatches)
381 {
382 bFilterApplies = true;
383 return 0;
384 }
385 }
386 }
387 });
388
389 return bFilterApplies;
390 }
391
392
393function GetCurrentArea()
394{
395 CurrentLocation = window.location.href;
396
397 if (CurrentLocation.indexOf("video-games.7") != -1)
398 return "Video Games";
399 else if (CurrentLocation.indexOf("hangouts.8") != -1)
400 return "Video Games - Hangouts";
401 else if (CurrentLocation.indexOf("etcetera.9") != -1)
402 return "EtcetEra";
403 else if (CurrentLocation.indexOf("hangouts.10") != -1)
404 return "EtcetEra - Hangouts";
405
406}
407
408function AddToWordFilter(event) {
409 newWord = $('#AddWordText').val();
410
411 var addWord = {};
412 addWord.Word = newWord;
413 addWord.Type = $('input[name*=AddWordType]:checked').val();
414 addWord.Area = $('input[name*=AddWordArea]:checked').val();
415
416 WordList = GetListFromLocalStorage('WordList');
417 nWordIndex = containsObject(addWord.Word, WordList);
418
419 if (nWordIndex == -1) {
420
421 WordList.push(addWord);
422 }
423
424 localStorage.setItem('WordList', JSON.stringify(WordList));
425 $('#AddWordText').val('');
426 $('input[name="AddWordArea"][value="All"]').prop('checked', true);
427 UpdateListing('WordListing', 'WordList');
428
429 localStorage.setItem("LastUpdate",new Date());
430 CheckCloudUpdateNeeded();
431
432}
433
434function AddToIgnoredUserList(event) {
435 newIgnoredUserText = $('#AddIgnoredUserText').val();
436
437 var addIgnoredUser = {};
438 addIgnoredUser.Username = newIgnoredUser;
439
440 IgnoredUserList = GetListFromLocalStorage('IgnoredUserList');
441 nIgnoredUserIndex = containsObject(addIgnoredUser.Username, IgnoredUserList);
442
443 if (nIgnoredUserIndex == -1) {
444 IgnoredUserList.push(addIgnoredUser);
445 }
446
447 localStorage.setItem('IgnoredUserList', JSON.stringify(IgnoredUserList));
448 $('#AddIgnoredUserText').val('');
449
450 UpdateListing('IgnoredUserListing', 'IgnoredUserList');
451
452 localStorage.setItem("LastUpdate",new Date());
453 CheckCloudUpdateNeeded();
454
455}
456
457function CreateControlPanel()
458{
459 var sControlPanel = "<div id='tabs' style='display:none;'>";
460 sControlPanel += "<ul>";
461 sControlPanel += "<li><a href='#tabs-1'>Word Filter</a></li>";
462 sControlPanel += "<li><a href='#tabs-2'>Ignored Threads</a></li>";
463 sControlPanel += "<li><a href='#tabs-3'>Ignored Users</a></li>";
464 sControlPanel += "<li><a href='#tabs-4'>Settings</a></li>";
465 sControlPanel += "</ul>";
466 sControlPanel += "<div id='tabs-1'>";
467 sControlPanel += CreateWordFilter();
468 sControlPanel += "</div>";
469 sControlPanel += "<div id='tabs-2'>";
470 sControlPanel += "<div id='RecentlyIgnoredListing'></div>";
471 sControlPanel += "</div>";
472 sControlPanel += "<div id='tabs-3'>";
473 sControlPanel += CreateIgnoredUserTab();
474 sControlPanel += "</div>";
475 sControlPanel += "<div id='tabs-4'>";
476 sControlPanel += CreateSettingsOptions();
477 sControlPanel += "</div>";
478 sControlPanel += "</div>";
479
480 if (isInMainForums){
481 $('.forumNodeInfo.primaryContent').parent().append(sControlPanel);
482 $('.forumNodeInfo.primaryContent').parent().append($('<a id="OpenFilterCP" class="large-button submit">Filter CP</a>'));
483 }
484 else{
485 $('.titleBar').append(sControlPanel);
486 $('.titleBar').append($('<a id="OpenFilterCP" class="large-button submit">Filter CP</a>'));
487 }
488
489
490
491}
492
493function CreateWordFilter()
494{
495 sWordFilter = "<div id='WordFilter'>";
496 sWordFilter += "<strong>Add New Word:</strong> <input id='AddWordText'><input type='button' id='AddWordButton' value='Add'><br />";
497 sWordFilter += "<div style='margin-left:20px'><strong>Type</strong> - <input type='radio' name='AddWordType' value='plaintext' checked>Plain Text (* supported)<input type='radio' name='AddWordType' value='regularexpression'>Regular Expression</div><br />";
498 sWordFilter += "<div style='margin-left:20px'><strong>Area</strong> - <input type='radio' name='AddWordArea' value='All' checked>All <input type='radio' name='AddWordArea' value='Video Games'>Video Games <input type='radio' name='AddWordArea' value='Video Games - Hangouts'>Video Games - Hangouts <input type='radio' name='AddWordArea' value='EtcetEra'>EtcetEra <input type='radio' name='AddWordArea' value='EtcetEra - Hangouts'>EtcetEra - Hangouts</div>";
499 sWordFilter += "<br /><br /><hr width='100%' color='black'><div id='WordListing'></div>";
500 sWordFilter += "</div>";
501
502 return sWordFilter;
503}
504
505function CreateIgnoredUserTab()
506{
507 sIgnoredUserTab = "<hr width='100%' color='black'><div id='IgnoredUserListing'></div>";
508
509 return sIgnoredUserTab;
510}
511
512function CreateSettingsOptions()
513{
514 sCreateSettings = "<strong>Hide Link Style</strong><br /><input type='radio' name='HideLinkStyle' checked='true' value='X'>X <input type='radio' name='HideLinkStyle' value='HideShow'>Hide/Show";
515
516 sCreateSettings += "<br /><br />";
517 sCreateSettings += "<input type='checkbox' id='SearchAdditional' checked='true'>Search additional pages for threads</input>";
518
519 sCreateSettings += "<br />";
520 sCreateSettings += "<input type='checkbox' id='ThreadExpiration'>Thread Expiration</input>";
521 sCreateSettings += "<div id='ThreadExpirationOptions' style='display:none;margin-left:30px'>";
522 sCreateSettings += "Remove threads from filter after <select id='ExpirationDays'>";
523
524 for (var i = 1; i < 31; i++)
525 sCreateSettings += "<option>" + i +"</option>";
526
527 sCreateSettings += "</select> day(s).";
528 sCreateSettings += "</div>";
529
530 sCreateSettings += "<br />";
531 sCreateSettings += "<input type='checkbox' id='CloudSync'>Cloud sync</input>";
532 sCreateSettings += "<br /><div id='CloudSyncOptions' style='display:none;float:left;margin-left:30px'><br />";
533 sCreateSettings += "Update Frequency:<br />";
534 sCreateSettings += "<select id='CloudSyncFrequency'>";
535 sCreateSettings += "<option value='Instant'>Instant</option>";
536 sCreateSettings += "<option value='1'>1 minute</option>";
537 sCreateSettings += "<option value='5'>5 minutes</option>";
538 sCreateSettings += "<option value='10'>10 minutes</option>";
539 sCreateSettings += "</select>";
540
541 sCreateSettings += "<br /><br />Sync Key:";
542 sCreateSettings += "<br /><div style='float:left'><input id='CloudSyncKey'></div><div style='float:left;margin-left:15px;vertical-align:middle'><input type='button' id='GenerateCloudSyncKey' value='Generate'></div>";
543 sCreateSettings += "<br /><br /><br />To sync up your settings with the cloud, enter your sync key above. To create a new key, click the generate button.";
544 sCreateSettings += "<div id='CloudKeyNotFoundMessage' style='display:none;color:red'><br />Sorry, the sync key you entered was not found. Please try another key or generate a new one.</div>";
545 sCreateSettings += "<div id='LastCloudUpdate' style='display:none;'><br />Last cloud update was at: <strong><div id='LastCloudUpdateTime'></div></strong></div>";
546 sCreateSettings += "</div>";
547 return sCreateSettings;
548}
549
550function CheckSettingOption(sSetting)
551{
552 if (sSetting == "HideLinkStyle")
553 $('input[name="HideLinkStyle"][value="' + localStorage.getItem(sSetting) + '"]').prop('checked', true);
554 else
555 {
556 if (localStorage.getItem(sSetting))
557 $("#" + sSetting).attr("checked", localStorage.getItem(sSetting) == "true" ? true : false);
558 else if (sSetting != "CloudSync" && sSetting != "ThreadExpiration")
559 localStorage.setItem(sSetting, "true");
560 }
561
562}
563
564function OpenFilterCP()
565 {
566 UpdateListing('WordListing', 'WordList');
567 UpdateListing('RecentlyIgnoredListing', 'IgnoreList');
568 UpdateListing('IgnoredUserListing', 'IgnoredUserList');
569 ShowCloudSyncOptions();
570
571 $('#tabs').tabs();
572 $('#tabs').dialog();
573 $('#tabs').bind('dialogclose', function(event) { CheckExpiredThreads(); UpdateThreads(); UpdateHideLinks(); });
574 $('#tabs').dialog({ title: "Filter Control Panel"});
575 $("#tabs").dialog("option", "width", '60%');
576 }
577
578function UpdateListing(sListingDiv, sListName)
579{
580 $('#' + sListingDiv).empty();
581 CurrentList = GetListFromLocalStorage(sListName);
582
583 if (sListName == 'IgnoreList' || sListName == 'IgnoredUserList')
584 CurrentList.reverse();
585
586 var sListingText;
587
588 if (sListName == 'IgnoredUserList')
589 sColumnHeadings = '<td align="center" width="300px"><strong>Username</strong></td>';
590 else if (sListName == 'IgnoreList')
591 sColumnHeadings = '<td align="center" width="300px"><strong>Title</strong></td>';
592 else if (sListName == 'WordList')
593 sColumnHeadings = '<td align="center" width="200px"><strong>Word</strong></td><td align="center" width="200px"><strong>Type</strong></td><td align="center" width="100px"><strong>Area</strong></td>';
594
595 sListingText = '<table width="100%"><tr>' + sColumnHeadings + '<td> </td></tr>';
596
597
598 jQuery.each(CurrentList,function (index)
599 {
600 if (sListName == 'IgnoredUserList')
601 sListingText += '<tr><td align="center"><div style="word-wrap:break-word;width:300px"><a href="https://www.resetera.com/members/' + this.ID + '/" target="_blank">' + this.Username + '</a></div></td><td><input type=button id="RemoveIgnoredUser' + this.ID + '" value=Unignore /></td></tr>';
602 else if (sListName == 'IgnoreList')
603 sListingText += '<tr><td align="center"><div style="word-wrap:break-word;width:300px"><a href="https://www.resetera.com/members/' + this.ID + '/" target="_blank">' + this.Title + '</a></div></td><td><input type=button id="RemoveRecentlyIgnored' + this.ID + '" value=Unignore /></td></tr>';
604 else if (sListName == 'WordList')
605 sListingText += '<tr><td align="center"><div style="word-wrap:break-word;width:200px">' + this.Word + '</div></td><td align="center">' + this.Type + '</td><td align="center">' + (this.Area != null ? this.Area : 'All') + '</td><td><input type=button id="RemoveWord' + index + '" value=Remove /></td></tr>';
606
607 });
608
609 sListingText += '</table>';
610
611 $('#' + sListingDiv).append(sListingText);
612
613 jQuery.each(CurrentList,function (index)
614 {
615 if (sListName == 'IgnoredUserList')
616 $('#RemoveIgnoredUser' + this.ID).click({sCurrentID: this.ID, sListName: 'IgnoredUserList', sListDiv: 'IgnoredUserListing'}, RemoveIgnored);
617 else if (sListName == 'IgnoreList')
618 $('#RemoveRecentlyIgnored' + this.ID).click({sCurrentID: this.ID, sListName: 'IgnoreList', sListDiv: 'RecentlyIgnoredListing'}, RemoveIgnored);
619 else if (sListName == 'WordList')
620 $('#RemoveWord' + index).click({sCurrentID: this.Word, sListName: 'WordList', sListDiv: 'WordListing'}, RemoveIgnored);
621
622 });
623}
624
625
626function RemoveIgnored(event) {
627 IgnoreList = GetListFromLocalStorage(event.data.sListName);
628 nCurrentIndex = containsObject(event.data.sCurrentID,IgnoreList);
629 IgnoreList.splice(nCurrentIndex,1);
630 localStorage.setItem(event.data.sListName, JSON.stringify(IgnoreList));
631
632 UpdateListing(event.data.sListDiv,event.data.sListName);
633
634 localStorage.setItem("LastUpdate",new Date());
635 CheckCloudUpdateNeeded();
636}
637
638function containsObject(id, list, addItem)
639{
640 if (list.length > 0)
641 {
642 if (list[0].hasOwnProperty('ID'))
643 return binaryIndexOf(id,list,addItem);
644 else
645 {
646 for (var i = 0; i < list.length; i++)
647 if (list[i].ID == id || list[i].Word == id)
648 return i;
649 }
650 }
651 else if (typeof addItem === 'object')
652 list.splice(0, 0, addItem);
653
654 return -1;
655}
656
657
658function binaryIndexOf(id,list,addItem) {
659 'use strict';
660 var minIndex = 0;
661 var maxIndex = list.length - 1;
662 var currentIndex;
663 var currentElement;
664
665 if (localStorage.getItem("IgnoredThreadsSorted") != "true")
666 {
667 list = list.sort(sortByID);
668 localStorage.setItem("IgnoreList",JSON.stringify(list));
669 localStorage.setItem("IgnoredThreadsSorted","true");
670 }
671
672 if ((parseInt(id) < parseInt(list[minIndex].ID) || parseInt(id) > parseInt(list[maxIndex].ID)) && typeof addItem === 'undefined')
673 return -1;
674
675 while (minIndex <= maxIndex) {
676 currentIndex = (minIndex + maxIndex) / 2 | 0;
677 currentElement = list[currentIndex].ID;
678
679 if (parseInt(currentElement) < parseInt(id)) {
680 minIndex = currentIndex + 1;
681 }
682 else if (parseInt(currentElement) > parseInt(id)) {
683 maxIndex = currentIndex - 1;
684 }
685 else {
686 if (typeof addItem === 'undefined')
687 return currentIndex;
688 else
689 {
690 list.splice(currentIndex,1);
691 //localStorage.setItem('IgnoreList', JSON.stringify(list));
692 writeignored(list);
693 return currentIndex;
694 }
695 }
696 }
697
698
699 if (typeof addItem === 'undefined')
700 return -1;
701 else
702 {
703 //console.log(minIndex + ' - ' + maxIndex + ' - ' + addItem.ID + ' - ' + addItem.Title);
704 list.splice(minIndex, 0, addItem);
705
706 //localStorage.setItem('IgnoreList', JSON.stringify(list));
707 }
708}
709
710function writeignored(list)
711{
712 for (var i = 0; i < list.length; i++)
713 console.log(list[i].ID);
714}
715
716function sortByID(a, b)
717{
718 return a.ID - b.ID;
719}
720
721
722function GetNextPage()
723{
724 var str = window.location.href;
725 var res = str.match("page-[0-9]+");
726
727 if (res)
728 return parseInt(res[0].replace("page-","")) + 1;
729 else
730 return 2;
731
732}
733
734function GetListFromLocalStorage(sListName)
735{
736 return localStorage.getItem(sListName) ? JSON.parse(localStorage.getItem(sListName)) : [];
737}
738
739function CheckExpiredThreads()
740{
741 if (localStorage.getItem("ThreadExpiration") == "true")
742 {
743 if (!localStorage.getItem("LastExpirationCheck"))
744 localStorage.setItem("LastExpirationCheck",new Date());
745
746 var checkexpirationdate = new Date(localStorage.getItem("LastExpirationCheck"));
747 checkexpirationdate.setDate(checkexpirationdate.getDate() + 1);
748
749 if (new Date() >= checkexpirationdate)
750 {
751 var madechange = false;
752 var expirationdays = parseInt(localStorage.getItem("ExpirationDays"));
753 var threadexpiration;
754
755 ignoreList = GetListFromLocalStorage('IgnoreList');
756
757 for (i = 0; i < ignoreList.length; i++)
758 {
759 if (typeof ignoreList[i].AddDate === 'undefined')
760 {
761 ignoreList[i].AddDate = new Date();
762 madechange = true;
763 }
764 else
765 {
766 threadexpiration = new Date(ignoreList[i].AddDate);
767 threadexpiration.setDate(threadexpiration.getDate() + expirationdays);
768
769 if (new Date() >= threadexpiration)
770 {
771 ignoreList.splice(i,1);
772 madechange = true;
773 }
774 }
775 }
776
777 if (madechange == true)
778 {
779 localStorage.setItem("IgnoreList",JSON.stringify(ignoreList));
780 SaveLastUpdate();
781 CheckCloudUpdateNeeded();
782 }
783
784 localStorage.setItem("LastExpirationCheck",new Date());
785 }
786
787 }
788}
789
790var Type = "POST";
791var URL;
792var URLPrefix = "http://ec2-54-149-209-12.us-west-2.compute.amazonaws.com/HideThreads/api/HideThreads/";
793var Data = {};
794var ContentType = "application/json; charset=utf-8";
795var DataType = "json";
796
797function CheckCloudSync()
798{
799 if (localStorage.getItem("CloudSync") == "true" && localStorage.getItem("CloudSyncKey"))
800 {
801 CheckCloudUpdateNeeded();
802
803 if (localStorage.getItem("CloudSyncFrequency") != 'Instant')
804 setInterval(CheckCloudUpdateNeeded, 1000 * 60);
805 }
806}
807
808function GetCloudSyncDateSucceeded(result)
809{
810 if (!localStorage.getItem("CloudSyncFrequency"))
811 localStorage.setItem("CloudSyncFrequency","5");
812
813 currentDate = new Date();
814
815 if (localStorage.getItem("CloudSyncFrequency") != 'Instant')
816 {
817 nextDate = new Date(localStorage.getItem("CloudSyncDate"));
818 nextDate.setTime(nextDate.getTime() + parseInt(localStorage.getItem("CloudSyncFrequency")) * 60 * 1000);
819 }
820 else
821 nextDate = currentDate;
822
823 date2 = localStorage.getItem("CloudSyncDate") ? new Date(localStorage.getItem("CloudSyncDate")) : new Date();
824 date1 = new Date(result);
825
826 //console.log(date1 + ' - ' + date2);
827
828 if (result != 'None')
829 {
830 CloudKeyFound();
831
832 if (!result || (result && localStorage.getItem("CloudSyncDate") && date2 > date1) || (currentDate >= nextDate && new Date(localStorage.getItem("LastUpdate")) > new Date(localStorage.getItem("CloudSyncDate"))))
833 SendInfoToCloud(new Date());
834 else if (!localStorage.getItem("CloudSyncDate") || (result && localStorage.getItem("CloudSyncDate") && date1 > date2))
835 GetInfoFromCloud();
836 }
837 else if (localStorage.getItem("CloudSyncKey"))
838 CloudKeyNotFound();
839
840}
841
842function ShowCloudSyncOptions()
843{
844 $('#CloudSyncOptions').css('display',$('#CloudSync').prop('checked') ? 'block' : 'none');
845
846 if (!localStorage.getItem('CloudSyncFrequency'))
847 localStorage.setItem('CloudSyncFrequency','5');
848
849 $('#CloudSyncFrequency').val(localStorage.getItem('CloudSyncFrequency'));
850}
851
852
853function GetInfoFromCloud()
854{
855 URL = "GetHideForumThreadsInfoNew?Key=" + localStorage.getItem("CloudSyncKey");
856 Data = "";
857 CallService(GetHideForumThreadsInfo);
858}
859
860function GetHideForumThreadsInfo(result) {
861 if (result.CloudSyncDate != null)
862 {
863 localStorage.setItem("CloudSyncDate",result.CloudSyncDate);
864 localStorage.setItem("SearchAdditional",result.SearchAdditional);
865 localStorage.setItem("ThreadFilter",result.ThreadFilter);
866 localStorage.setItem("IgnoredThreadsSorted",result.IgnoredThreadsSorted);
867 localStorage.setItem("ThreadExpiration",result.ThreadExpiration);
868 localStorage.setItem("ExpirationDays",result.ExpirationDays);
869 localStorage.setItem("LastExpirationCheck",result.LastExpirationCheck);
870 localStorage.setItem("IgnoredUserList",result.IgnoredUserList);
871 localStorage.setItem("IgnoreList",result.IgnoreList);
872 localStorage.setItem("WordList",result.WordList);
873 localStorage.setItem("HideLinkStyle",result.HideLinkStyle);
874
875 console.log("info received from cloud");
876
877 SetOptions();
878 RemoveHideLinks();
879
880 CloudKeyFound();
881 }
882 else
883 CloudKeyNotFound();
884
885
886}
887
888function SaveLastUpdate()
889{
890 localStorage.setItem("LastUpdate",new Date());
891}
892
893function CloudKeyChanged(CurrentKey)
894{
895 localStorage.setItem("CloudSyncKey",CurrentKey);
896
897 if (CurrentKey != '')
898 GetInfoFromCloud();
899 else
900 CloudKeyNotFound();
901}
902
903function CloudKeyFound()
904 {
905 $('#CloudKeyNotFoundMessage').hide();
906 ShowLastCloudUpdate();
907
908 }
909
910function CloudKeyNotFound()
911 {
912 $('#CloudKeyNotFoundMessage').show();
913 $('#LastCloudUpdate').hide();
914 }
915
916
917
918function ShowLastCloudUpdate()
919{
920 document.getElementById("LastCloudUpdateTime").innerHTML = localStorage.getItem("CloudSyncDate");
921 $('#LastCloudUpdate').show();
922}
923
924function GenerateCloudSyncKey()
925{
926 localStorage.setItem("CloudSyncKey","None");
927 SendInfoToCloud(new Date());
928}
929
930function SendInfoToCloud(currentDate)
931{
932 localStorage.setItem("CloudSyncDate",currentDate);
933
934$.ajax({
935 url: URLPrefix + "UpdateHideForumThreadsInfoNew",
936 type: "POST",
937 data: {Key:localStorage.getItem("CloudSyncKey"),
938 CloudSyncDate: currentDate,
939 SearchAdditional: localStorage.getItem("SearchAdditional") ? localStorage.getItem("SearchAdditional") : "",
940 ThreadFilter: localStorage.getItem("ThreadFilter") ? localStorage.getItem("ThreadFilter") : "",
941 IgnoredThreadsSorted: localStorage.getItem("IgnoredThreadsSorted") ? localStorage.getItem("IgnoredThreadsSorted") : "",
942 ThreadExpiration: localStorage.getItem("ThreadExpiration") ? localStorage.getItem("ThreadExpiration") : "",
943 ExpirationDays: localStorage.getItem("ExpirationDays") ? localStorage.getItem("ExpirationDays") : "",
944 LastExpirationCheck: localStorage.getItem("LastExpirationCheck") ? localStorage.getItem("LastExpirationCheck") : "",
945 IgnoredUserList: localStorage.getItem("IgnoredUserList") ? localStorage.getItem("IgnoredUserList") : "[]",
946 IgnoreList: localStorage.getItem("IgnoreList") ? localStorage.getItem("IgnoreList") : "[]",
947 WordList: localStorage.getItem("WordList") ? localStorage.getItem("WordList") : "[]",
948 HideLinkStyle: localStorage.getItem("HideLinkStyle") ? localStorage.getItem("HideLinkStyle") : "X",
949 Username: GetUsername()},
950 success: Success,
951 dataType: "json",
952 error: ServiceFailed
953
954});
955
956}
957
958function GetUsername()
959{
960 Username = $('#usercptools').text().replace('Welcome ','');
961
962 UsernamePattern = new RegExp("([A-Za-z0-9]+)");
963 FoundUsername = UsernamePattern.exec(Username);
964
965 if (FoundUsername != null)
966 return FoundUsername[0].toString();
967 else
968 return "None";
969}
970
971function Success(result)
972{
973 localStorage.setItem("CloudSyncKey", result);
974 document.getElementById("CloudSyncKey").value = localStorage.getItem("CloudSyncKey");
975 CloudKeyFound();
976 console.log("info sent to cloud");
977}
978
979function CheckCloudUpdateNeeded()
980{
981 if (localStorage.getItem("CloudSync") == "true" && localStorage.getItem("CloudSyncKey"))
982 {
983 URL = "GetCloudSyncDate?Key=" + localStorage.getItem("CloudSyncKey");
984 CallService(GetCloudSyncDateSucceeded);
985 }
986}
987
988// Function to call WCF Service
989function CallService(succeededcallback) {
990 $.ajax({
991 type: Type, //GET or POST or PUT or DELETE verb
992 url: URLPrefix + URL, // Location of the service
993 contentType: ContentType, // content type sent to server
994 dataType: DataType, //Expected data format from server
995 data: Data,
996 processdata: true, //True or False
997 success: function(msg) {//On Successful service call
998 indirectCaller(succeededcallback,msg);
999 },
1000 error: ServiceFailed// When Service call fails
1001 });
1002}
1003
1004function ServiceFailed(xhr) {
1005 console.log('error - ' + xhr.responseText);
1006
1007 if (xhr.responseText) {
1008 var err = xhr.responseText;
1009 if (err)
1010 error(err);
1011 else
1012 error({ Message: "Unknown server error." });
1013 }
1014 return;
1015}
1016
1017function indirectCaller(f,msg) {
1018 // Call `caller`, who will in turn call `f`
1019 f(msg);
1020}