1
1
// ==UserScript==
2
2
// @name UnityForumFixer
3
3
// @namespace https://unitycoder.com/
4
- // @version 0.5 (26.08.2024)
4
+ // @version 0.51 (26.08.2024)
5
5
// @description Fixes For Unity Forums - https://github.com/unitycoder/UnityForumFixer
6
6
// @author unitycoder.com
7
7
// @match https://discussions.unity.com/latest
8
8
// @match https://discussions.unity.com/t/*
9
- // @grant none
9
+ // @grant GM.xmlHttpRequest
10
10
// ==/UserScript==
11
11
12
+
12
13
( function ( ) {
13
14
'use strict' ;
14
15
22
23
TopicsViewShowOriginalPosterInfo ( ) ; // TODO needs some css adjustments for name location
23
24
FixPostActivityTime ( ) ;
24
25
PostViewShowOriginalPosterInfo ( ) ;
25
- TopicsViewCombineViewAndReplyCounts ( ) ;
26
+ TopicsViewCombineViewAndReplyCounts ( ) ;
27
+
26
28
setTimeout ( OnUpdate , 1000 ) ; // run loop to update activity times (since some script changes them back to original..)
27
29
} ) ;
30
+
28
31
} ) ( ) ;
29
32
30
33
// runs every second to update things (if you scroll the page, need to update new data)
@@ -34,6 +37,8 @@ function OnUpdate()
34
37
FixPostActivityTime ( ) ;
35
38
TopicsViewShowOriginalPosterInfo ( ) ;
36
39
PostViewShowOriginalPosterInfo ( ) ;
40
+ PostViewFetchOPDetails ( ) ;
41
+
37
42
setTimeout ( OnUpdate , 1000 ) ;
38
43
}
39
44
@@ -98,7 +103,7 @@ function AppendCustomCSS()
98
103
.user-name:hover { color: rgb(82,132,189); text-decoration: underline; }
99
104
.names.trigger-user-card {visibility: hidden !important;}
100
105
/* .row { display: flex; } */
101
- .topic-avatar { flex-basis: 10%; margin:0 !important; }
106
+ .topic-avatar { flex-basis: 10%; margin:0 !important; max-width: 45px; }
102
107
.topic-body { flex-basis: 90%; } /* Ensure the main content adjusts accordingly */
103
108
.topic-avatar {background-color: #d1d1d132;}
104
109
.post-avatar { display: flex; flex-direction: column; align-items: center; }
@@ -107,6 +112,8 @@ function AppendCustomCSS()
107
112
.topic-map.--op {display: none !important;} /* hide view count under op post, could move it somewhere else later */
108
113
109
114
.user-signature {max-height:32px; overflow:hidden;padding: 8px 8px 4px 24px !important;} /* max size for signature */
115
+ .avatar-flair {top:55px; right: -2px; bottom:unset !important;}
116
+
110
117
111
118
.more-topics__container {display:none !important;} /* hide suggested topics at bottom */
112
119
/* unity footer & content - could hide it.. but then unity is sad*/
@@ -123,8 +130,8 @@ function AppendCustomCSS()
123
130
.combined-views-container {display: flex;justify-content: space-between;width: 100%;white-space: nowrap; font-size:13px;}
124
131
.combined-views-label {color: rgb(150, 150, 150); text-align: left;}
125
132
.combined-views-number {color: var(--primary); margin-left: auto;text-align: right;}
126
- .custom-post-username {color: var(--primary);}
127
-
133
+ .custom-post-username {margin-bottom:3px; color: var(--primary);}
134
+ .custom-user-creation-date {width:45px;margin-top:6px;font: 13px 'Inter', sans-serif !important; color: rgb(150, 150, 150);}
128
135
129
136
` ;
130
137
document . head . appendChild ( style ) ;
@@ -331,8 +338,100 @@ function PostViewShowOriginalPosterInfo()
331
338
// Insert the user name link before the avatar image
332
339
avatar . parentNode . insertBefore ( userLink , avatar ) ;
333
340
} ) ;
341
+
342
+ }
343
+
344
+ let prevPageURL = '' ;
345
+ function PostViewFetchOPDetails ( )
346
+ {
347
+ // Get the current page URL
348
+ const currentPageURL = window . location . href ;
349
+
350
+ // Check if the current page URL has already been processed
351
+ if ( currentPageURL === prevPageURL ) {
352
+ console . log ( `Skipping fetch for already processed page URL: ${ currentPageURL } ` ) ;
353
+ return ; // Skip execution if the URL has already been processed
354
+ }
355
+
356
+ // Update the previous page URL to the current one
357
+ prevPageURL = currentPageURL ;
358
+
359
+ // Select all elements with the specified classes to get usernames
360
+ const usernames = new Set ( ) ; // Using a Set to avoid duplicates
361
+
362
+ // Find usernames from elements with class 'trigger-user-card main-avatar'
363
+ document . querySelectorAll ( '.trigger-user-card.main-avatar' ) . forEach ( function ( avatar ) {
364
+ const userName = avatar . getAttribute ( 'data-user-card' ) ;
365
+ if ( userName ) {
366
+ usernames . add ( userName ) ; // Add to the Set
367
+ }
368
+ } ) ;
369
+
370
+ // Convert the Set to an Array and limit to the first 3 users
371
+ const userArray = Array . from ( usernames ) . slice ( 0 , 3 ) ;
372
+
373
+ // Iterate through each of the first three unique usernames and fetch the JSON data
374
+ userArray . forEach ( function ( userName ) {
375
+ const url = `https://discussions.unity.com/u/${ userName } /card.json` ;
376
+
377
+ console . log ( `Fetching data from: ${ url } ` ) ;
378
+
379
+ // Use fetch to make a cross-origin request
380
+ fetch ( url , {
381
+ method : 'GET' ,
382
+ headers : {
383
+ 'User-Agent' : navigator . userAgent , // Mimic the default browser's User-Agent
384
+ 'Accept' : 'application/json, text/javascript, */*; q=0.01' // Accept JSON
385
+ }
386
+ } )
387
+ . then ( response => {
388
+ if ( ! response . ok ) {
389
+ throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
390
+ }
391
+ return response . json ( ) ; // Parse the JSON data
392
+ } )
393
+ . then ( data => {
394
+ console . log ( `Data for ${ userName } :` , data ) ; // Print the JSON data to console
395
+
396
+ // Get the user creation date
397
+ const createdAt = data . user . created_at ;
398
+ if ( createdAt ) {
399
+ // Format the creation date (optional)
400
+ const formattedDate = new Date ( createdAt ) . toLocaleDateString ( 'en-US' , {
401
+ year : 'numeric' ,
402
+ month : 'long' ,
403
+ day : 'numeric'
404
+ } ) ;
405
+
406
+ // Create a new element to display the creation date
407
+ const creationDateElement = document . createElement ( 'span' ) ;
408
+ creationDateElement . className = 'custom-user-creation-date' ;
409
+ creationDateElement . textContent = `Joined: ${ formattedDate } ` ;
410
+
411
+ // Find all post-avatar divs associated with this user
412
+ document . querySelectorAll ( '.trigger-user-card.main-avatar' ) . forEach ( function ( avatarElement ) {
413
+ if ( avatarElement . getAttribute ( 'data-user-card' ) === userName ) {
414
+ const postAvatarDiv = avatarElement . closest ( '.post-avatar' ) ;
415
+ if ( postAvatarDiv && ! postAvatarDiv . querySelector ( '.custom-user-creation-date' ) ) {
416
+ postAvatarDiv . appendChild ( creationDateElement . cloneNode ( true ) ) ; // Append the new date element to all relevant divs
417
+ }
418
+ }
419
+ } ) ;
420
+ }
421
+ } )
422
+ . catch ( error => {
423
+ console . error ( `Failed to fetch or parse JSON for user ${ userName } :` , error ) ;
424
+ } ) ;
425
+ } ) ;
334
426
}
335
427
428
+ // TODO: if page uses AJAX navigation, can run this function again when the URL changes without a full reload.
429
+ /*
430
+ window.addEventListener('popstate', function() {PostViewFetchOPDetails();});
431
+ window.addEventListener('pushstate', function() {PostViewFetchOPDetails();});
432
+ window.addEventListener('replacestate', function() {PostViewFetchOPDetails();});
433
+ */
434
+
336
435
337
436
338
437
// HELPER METHODS
0 commit comments