mirror of
				https://gitlab.com/octtspacc/Friendiiverse
				synced 2025-06-05 21:49:22 +02:00 
			
		
		
		
	Restructuring of DOM management
This commit is contained in:
		
							
								
								
									
										1
									
								
								Source/ApiStatic.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								Source/ApiStatic.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| /* | ||||
| var TransSchemas = { | ||||
| 	Mastodon: { | ||||
| 		Account: { | ||||
| @@ -18,17 +19,25 @@ var TransSchemas = { | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| */ | ||||
|  | ||||
| var ApiSchema = { | ||||
| 	__Account__: { | ||||
| 		Banner: { | ||||
| 			Mastodon: "header", | ||||
| 			Misskey: "bannerUrl", | ||||
| 		}, | ||||
| 		Description: { | ||||
| 			Mastodon: "note", | ||||
| 			Misskey: "description", | ||||
| 		}, | ||||
| 		Icon: { | ||||
| 			Mastodon: "avatar", | ||||
| 			Misskey: "avatarUrl", | ||||
| 		}, | ||||
| 		Name: { | ||||
| 			Mastodon: "display_name", | ||||
| 			Misskey: "name", | ||||
| 		}, | ||||
| 		Url: { | ||||
| 			Mastodon: "url", | ||||
| @@ -37,12 +46,15 @@ var ApiSchema = { | ||||
| 	Note: { | ||||
| 		Author: { | ||||
| 			Mastodon: "account", | ||||
| 			Misskey: "user", | ||||
| 		}, | ||||
| 		Content: { | ||||
| 			Mastodon: "content", | ||||
| 			Misskey: "text", | ||||
| 		}, | ||||
| 		Time: { | ||||
| 			Mastodon: "created_at", | ||||
| 			Misskey: "createdAt", | ||||
| 		}, | ||||
| 		Url: { | ||||
| 			Mastodon: "url", | ||||
| @@ -54,15 +66,19 @@ ApiSchema.Channel = CopyObj(ApiSchema.__Account__); | ||||
|  | ||||
| var TransParsers = { | ||||
| 	Mastodon: { | ||||
| 		/* | ||||
| 		Account(Data) { | ||||
| 			return JsonTransformA(Data, TransSchemas.Mastodon.Author, TransSchemas.Mastodon); | ||||
| 		}, | ||||
| 		Instance(Data) { | ||||
| 			return JsonTransformA(Data, TransSchemas.Mastodon.Instance, TransSchemas.Mastodon); | ||||
| 		}, | ||||
| 		*/ | ||||
| 		Status(Data) { | ||||
| 			//return JsonTransformA(Data, TransSchemas.Mastodon.Status, TransSchemas.Mastodon); | ||||
| 			return JsonTransformB(Data, ApiSchema, ApiSchema.Note, 'Mastodon'); | ||||
| 		}, | ||||
| 	}, | ||||
| 	Misskey: { | ||||
| 	}, | ||||
| }; | ||||
|   | ||||
| @@ -24,6 +24,7 @@ FakeApi.Friendiiverse.Featured.Categories.push({ | ||||
| FakeApi.Mastodon.Account = { | ||||
| 	avatar: "https://picsum.photos/seed/Tester.Icon/64", | ||||
| 	display_name: "The Tester", | ||||
| 	header: "https://picsum.photos/seed/Tester.Banner/320/180", | ||||
| 	url: "https://mastodon.example.com/@Tester", | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -16,7 +16,7 @@ var UseFakeApi = true; | ||||
| 		</script> | ||||
| 	</head> | ||||
| 	<body> | ||||
| 	<main> | ||||
| 		<div id="Root"> | ||||
| 			<div id="CoverView"> | ||||
| 				LOGO | ||||
| 				Loading... | ||||
| @@ -24,15 +24,18 @@ var UseFakeApi = true; | ||||
| 			<div id="NoscriptView"> | ||||
| 				No Script! | ||||
| 			</div> | ||||
| 			<!-- | ||||
| 			<div id="PlazasView"></div> | ||||
| 			<textarea id="Input"></textarea> | ||||
| 			<button id="Post">Post</button> | ||||
| 			<div id="ChannelView"></div> | ||||
| 			<div id="TimelineView"></div> | ||||
| 			<xmp id="DataView"></xmp> | ||||
| 	</main> | ||||
| 	<footer> | ||||
| 			--> | ||||
| 		</div> | ||||
| 		<div id="Bottom"> | ||||
| 			<a href="https://gitlab.com/octtspacc/Friendiiverse">Source Code</a> | ||||
| 	</footer> | ||||
| 		</div> | ||||
| 		<script>NoscriptView.remove();</script> | ||||
| 		<script src="./Utils.js"></script> | ||||
| 		<script src="./Strings.js"></script> | ||||
|   | ||||
| @@ -26,6 +26,7 @@ function DoAsync(First, Then, Data) { | ||||
| 			ForceList(Then).forEach(function(Fun){ | ||||
| 				Fun(CurrTasks[Job].Result); | ||||
| 			}); | ||||
| 			delete CurrTasks[Job]; | ||||
| 		}; | ||||
| 	}, 50, Job, Then); | ||||
| 	return Job; | ||||
| @@ -77,6 +78,7 @@ function ApiCall(Data, Proc) { | ||||
| 	Req.send(); | ||||
| }; | ||||
|  | ||||
| /* | ||||
| function DisplayFriendicaTimeline(Timeline) { | ||||
| 	ApiCall({Target: "Friendica", Method: Timeline, CallFine: function(Res){ | ||||
| 		DataView.innerHTML = Res.responseText; | ||||
| @@ -91,6 +93,36 @@ function DisplayFriendicaTimeline(Timeline) { | ||||
| 		}); | ||||
| 	}}); | ||||
| }; | ||||
| */ | ||||
|  | ||||
| function MakeWindow(Attrs) { | ||||
| 	var Window = document.createElement('div'); | ||||
| 	if (Attrs) { | ||||
| 		Object.keys(Attrs).forEach(function(Attr){ | ||||
| 			Window[Attr] = Attrs[Attr]; | ||||
| 		}); | ||||
| 	}; | ||||
| 	Window.className += ' Window'; | ||||
| 	Root.appendChild(Window); | ||||
| 	return Window; | ||||
| }; | ||||
|  | ||||
| function DisplayChannel(Channel) { | ||||
| 	//DoAsync(FetchMastodon, FillTimeline); | ||||
| 	ChannelView.innerHTML = ` | ||||
| 		<div class="" style="display: inline-block;"> | ||||
| 			<a href="${Channel.Url}"> | ||||
| 				<div> | ||||
| 					<img class="" src="${Channel.Banner}"/> | ||||
| 				</div> | ||||
| 				<div> | ||||
| 					<img class="" src="${Channel.Icon}"/> | ||||
| 					${Channel.Name} | ||||
| 				</div> | ||||
| 			</a> | ||||
| 		</div> | ||||
| 	`; | ||||
| }; | ||||
|  | ||||
| function FetchMastodon(Proc) { | ||||
| 	if (UseFakeApi) { | ||||
| @@ -107,8 +139,8 @@ function ResFetchMastodon(Res) { | ||||
|  | ||||
| function FillTimeline(Notes) { | ||||
| 	Notes.forEach(function(Note){ | ||||
| 		TimelineView.innerHTML += `<div class="View Note"> | ||||
| 			<a href="${Note.Author.Url}"> | ||||
| 		TimelineView.innerHTML += `<div class="View Note" data-data="${B64Obj(Note)}"> | ||||
| 			<a href="${Note.Author.Url}" onclick="DisplayChannel(UnB64Obj(this.parentNode.dataset.data).Author); return false;"> | ||||
| 				<img class="Author Icon" src="${Note.Author.Icon}"/> | ||||
| 				${Note.Author.Name} | ||||
| 			</a> | ||||
| @@ -127,19 +159,25 @@ function FetchFeatured(Proc) { | ||||
| }; | ||||
|  | ||||
| function FillFeatured(Categories) { | ||||
| 	var Window = MakeWindow({className: "Gallery"}); | ||||
| 	Object.values(Categories).forEach(function(Channels){ | ||||
| 		Channels.forEach(function(Channel){ | ||||
| 			PlazasView.innerHTML += `<div> | ||||
| 				<a href="${Channel.Url}"> | ||||
| 					<img class="" src="${Channel.Banner}"/> | ||||
| 					<img class="" src="${Channel.Icon}"/> | ||||
| 			Window.innerHTML += `<div data-data="${B64Obj(Channel)}"> | ||||
| 				<a href="${Channel.Url}" onclick="DisplayChannel(UnB64Obj(this.parentNode.dataset.data).Author); return false;"> | ||||
| 					<div> | ||||
| 						<img src="${Channel.Banner}"/> | ||||
| 					</div> | ||||
| 					<div> | ||||
| 						<img src="${Channel.Icon}"/> | ||||
| 						${Channel.Name} | ||||
| 					</div> | ||||
| 				</a> | ||||
| 			</div>`; | ||||
| 		}); | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| /* | ||||
| PlazasView.innerHTML = ` | ||||
| <div> | ||||
| 	<h3>Featured</h3> | ||||
| @@ -160,6 +198,7 @@ PlazasView.innerHTML = ` | ||||
| 	</ul> | ||||
| </div> | ||||
| `; | ||||
| */ | ||||
|  | ||||
| DoAsync(FetchFeatured, FillFeatured); | ||||
|  | ||||
|   | ||||
| @@ -2,11 +2,11 @@ img, video { | ||||
| 	max-width: 100%; | ||||
| } | ||||
|  | ||||
| main { | ||||
| #Root { | ||||
| 	margin-bottom: 2em; | ||||
| } | ||||
|  | ||||
| footer { | ||||
| #Bottom { | ||||
| 	display: block; | ||||
| 	width: 100%; | ||||
| 	position: fixed; | ||||
| @@ -28,3 +28,7 @@ footer { | ||||
| .View.Note .Author.Icon { | ||||
| 	width: 64px; | ||||
| } | ||||
|  | ||||
| .Gallery > div { | ||||
| 	display: inline-block; | ||||
| } | ||||
|   | ||||
| @@ -20,10 +20,21 @@ function LogDebug(Data, Status) { | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| function IsObj(Item) { | ||||
| 	return typeof(Item) == 'object'; | ||||
| }; | ||||
|  | ||||
| function CopyObj(Obj) { | ||||
| 	return JSON.parse(JSON.stringify(Obj)); | ||||
| }; | ||||
|  | ||||
| function B64Obj(Obj) { | ||||
| 	return btoa(JSON.stringify(Obj)); | ||||
| }; | ||||
| function UnB64Obj(Obj) { | ||||
| 	return JSON.parse(atob(Obj)); | ||||
| }; | ||||
|  | ||||
| // Transform JSON tree into a new using a template schema | ||||
| // DEVNOTE: Unsafe, should check for colliding "__" keys from input tree and act accordingly | ||||
| function JsonTransformA(TreesOld, SchemaCurr, SchemaRoot) { | ||||
| @@ -41,8 +52,8 @@ function JsonTransformCycleA(TreeOld, SchemaCurr, SchemaRoot) { | ||||
| 	var TreeNew = {}; | ||||
| 	Object.keys(TreeOld).forEach(function(KeyOld){ | ||||
| 		var Content = TreeOld[KeyOld]; | ||||
| 		var KeyNew = ((typeof(SchemaCurr) == 'object' && KeyOld in SchemaCurr) ? SchemaCurr[KeyOld] : KeyOld); | ||||
| 		if (typeof(Content) == 'object' && Content !== null) { | ||||
| 		var KeyNew = ((IsObj(SchemaCurr) && KeyOld in SchemaCurr) ? SchemaCurr[KeyOld] : KeyOld); | ||||
| 		if (IsObj(Content) && Content !== null) { | ||||
| 			if (Array.isArray(Content)) { | ||||
| 			// Lists | ||||
| 			/*	var ListNew = []; | ||||
| @@ -87,12 +98,12 @@ function JsonTransformCycleB(TreeOld, SchemaNew, NodeNew, TypeOld) { | ||||
| 		if (TypeOld in TreeNew[KeyNew]) { | ||||
| 			var KeyOld = TreeNew[KeyNew][TypeOld]; | ||||
| 			var ObjOld = TreeOld[KeyOld]; | ||||
| 			if (typeof(KeyOld) == 'object') { | ||||
| 			if (IsObj(KeyOld)) { | ||||
| 			// Deep nested children in TreeOld | ||||
| 				 | ||||
| 			} else { | ||||
| 			// Direct children in TreeOld | ||||
| 				if (typeof(ObjOld) == 'object') { | ||||
| 				if (IsObj(ObjOld)) { | ||||
| 					TreeNew[KeyNew] = JsonTransformB(ObjOld, SchemaNew, SchemaNew[KeyNew], TypeOld); | ||||
| 				} else { | ||||
| 					TreeNew[KeyNew] = ObjOld; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user