This commit is contained in:
octospacc 2023-04-23 19:46:01 +02:00
parent 12d4db5953
commit 2fc970d24c
12 changed files with 113 additions and 91 deletions

View File

@ -22,7 +22,12 @@ var TransSchemas = {
*/ */
var ApiSchema = { var ApiSchema = {
Note: { // TODO: Figure out renotes __All__: {
SourceInstance: {
__Eval__: "",
},
},
Note: {
Content: { Content: {
Mastodon: "content", Mastodon: "content",
Misskey: "text", Misskey: "text",
@ -61,11 +66,10 @@ var ApiSchema = {
Misskey: "name", Misskey: "name",
}, },
Type: { // user, bot, channel, group Type: { // user, bot, channel, group
Mastodon: {"__Eval__": ` Mastodon: {__EvalSet__: `
var Type; if (TreeOld.bot) 'Bot';
if (TreeOld.bot) Type = 'Bot'; else
if (TreeOld.group) Type = 'Group'; if (TreeOld.group) 'Group';
TreeNew[KeyNew] = Type;
`}, `},
}, },
Url: { Url: {

BIN
App/Assets/Sample.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 990 B

11
App/Elems.js Normal file
View File

@ -0,0 +1,11 @@
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;
};

View File

@ -13,7 +13,11 @@ var FriendicaCredentials = 'redacted:redacted';
// Development // Development
var Debug = true; var Debug = true;
var UseFakeApi = true; var UseFakeApi = true;
var UserData = {}; </script>
<script data-build-json="true">
var Assets = {
ImgSample: "./Sample.jpg",
};
</script> </script>
</head> </head>
<body> <body>
@ -32,14 +36,19 @@ var UserData = {};
</div> </div>
<div id="Bottom"> <div id="Bottom">
<button onclick="Root.lastChild.remove();">↩️ Back</button> <button onclick="Root.lastChild.remove();">↩️ Back</button>
<button onclick="ComposeNote();">Note</button> <button onclick="ComposeNote();">📝 Note</button>
<button onclick="ManageSettings();">⚙️ Settings</button>
<button>Profile</button>
<a href="https://gitlab.com/octtspacc/Friendiiverse">📜️ Source Code</a> <a href="https://gitlab.com/octtspacc/Friendiiverse">📜️ Source Code</a>
<span>(Pre-Alpha Development Version)</span>
</div> </div>
<script>NoscriptView.remove();</script> <script>NoscriptView.remove();</script>
<script src="./Utils.js"></script> <script src="./Utils.js"></script>
<script src="./Strings.js"></script> <script src="./Strings.js"></script>
<script src="./ApiTransform.js"></script> <script src="./ApiTransform.js"></script>
<script src="./FakeApi.js"></script> <script src="./ApiFake.js"></script>
<script src="./Net.js"></script>
<script src="./Elems.js"></script>
<script src="./Main.js"></script> <script src="./Main.js"></script>
<script>(function(){ <script>(function(){
if (Debug && new URLSearchParams(window.location.hash).get('#Eruda')) { if (Debug && new URLSearchParams(window.location.hash).get('#Eruda')) {

View File

@ -1,5 +1,7 @@
var Persist = {Servers: {}, Sources: {}, Identities: {},};
var Present = CopyObj(Persist);
var Tasker = {}; var Tasker = {};
var ApiCache = {Notes: {}, Profiles: {},}; var ApiCache = {Urls: {},};
function DoAsync(First, Then, Data) { function DoAsync(First, Then, Data) {
var Job = RndId(); var Job = RndId();
@ -33,81 +35,6 @@ function DoAsync(First, Then, Data) {
return Job; return Job;
}; };
function HttpCodeGood(Code) {
var Unit = String(Code)[0];
if (['1', '2', '3'].includes(Unit)) {
return true;
} else
if (['4', '5'].includes(Unit)) {
return false;
};
};
function ApiCall(Data, Proc) {
// Data = {Target: "Friendica", Method: "...", Data: {}, Call: (), CallFine: (), CallFail: ()}
var Req = new XMLHttpRequest();
Req.Proc = Proc;
Req.onloadend = function(){
try {
this.responseJson = JSON.parse(this.responseText);
this.responseLog = this.responseJson;
} catch(Ex) {
this.responseLog = this.responseText;
};
if (Data.Call) {
Data.Call(this);
};
if (HttpCodeGood(this.status)) {
LogDebug([this.status, this.responseLog], 'l');
if (Data.CallFine) {
Data.CallFine(this);
};
} else {
LogDebug([this.status, this.responseLog], 'e');
if (Data.CallFail) {
Data.CallFail(this);
};
};
};
if (Data.Target == 'Mastodon') {
Req.open('GET', `${MastodonUrl}/api/v1/${Data.Method}`, true);
} else
if (Data.Target == 'Friendica') {
Req.open('GET', `${FriendicaUrl}/api/${Data.Method}.json`, true);
Req.setRequestHeader('Authorization', `Basic ${btoa(FriendicaCredentials)}`);
};
Req.send();
};
/*
function DisplayFriendicaTimeline(Timeline) {
ApiCall({Target: "Friendica", Method: Timeline, CallFine: function(Res){
DataView.innerHTML = Res.responseText;
JSON.parse(DataView.innerHTML).forEach(function(Item){
var Title = Item.friendica_title ? `<h2>${Item.friendica_title}</h2>` : '';
TimelineView.innerHTML += `<div class=PostView>
<a href="${Item.external_url}">${Item.created_at}</a>
${Item.friendica_author.url}
${Title}
${Item.friendica_html}
</div>`;
});
}});
};
*/
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 DisplayProfile(Profile) { function DisplayProfile(Profile) {
var Window = MakeWindow({className: "Profile"}); var Window = MakeWindow({className: "Profile"});
Window.innerHTML += `<div class="" style="display: inline-block;"> Window.innerHTML += `<div class="" style="display: inline-block;">
@ -121,7 +48,11 @@ function DisplayProfile(Profile) {
</div> </div>
</a> </a>
</div>`; </div>`;
DoAsync(FetchMastodon, FillTimeline); DoAsync(FetchMastodon, FillTimeline, Profile);
};
function FetchNotes(Profile, Proc) {
}; };
function FetchMastodon(Proc) { function FetchMastodon(Proc) {
@ -140,7 +71,7 @@ function ResFetchMastodon(Res) {
function FillTimeline(Notes) { function FillTimeline(Notes) {
Notes.forEach(function(Note){ Notes.forEach(function(Note){
Root.lastChild.innerHTML += `<div class="View Note"> Root.lastChild.innerHTML += `<div class="View Note">
<a href="${Note.Profile.Url}" onclick="DisplayProfile(ApiCache.Profiles['${Note.Profile.Url}']); return false;"> <a href="${Note.Profile.Url}" onclick="DisplayProfile(ApiCache.Urls['${Note.Profile.Url}']); return false;">
<img class="Profile Icon" src="${Note.Profile.Icon}"/> <img class="Profile Icon" src="${Note.Profile.Icon}"/>
${Note.Profile.Name} ${Note.Profile.Name}
</a> </a>
@ -155,7 +86,7 @@ function FetchFeatured(Proc) {
var Featured = FakeApi.Friendiiverse.Featured; var Featured = FakeApi.Friendiiverse.Featured;
Object.values(Featured).forEach(function(Profiles){ Object.values(Featured).forEach(function(Profiles){
Profiles.forEach(function(Profile){ Profiles.forEach(function(Profile){
ApiCache.Profiles[Profile.Url] = Profile; ApiCache.Urls[Profile.Url] = Profile;
}); });
}); });
Tasker[Proc[0]].Return(Featured); Tasker[Proc[0]].Return(Featured);
@ -169,7 +100,7 @@ function FillFeatured(Categories) {
Object.values(Categories).forEach(function(Profiles){ Object.values(Categories).forEach(function(Profiles){
Profiles.forEach(function(Profile){ Profiles.forEach(function(Profile){
Window.innerHTML += `<div> Window.innerHTML += `<div>
<a href="${Profile.Url}" onclick="DisplayProfile(ApiCache.Profiles['${Profile.Url}']); return false;"> <a href="${Profile.Url}" onclick="DisplayProfile(ApiCache.Urls['${Profile.Url}']); return false;">
<div> <div>
<img src="${Profile.Banner}"/> <img src="${Profile.Banner}"/>
</div> </div>
@ -203,6 +134,7 @@ function ComposeNote() {
var Window = MakeWindow(); var Window = MakeWindow();
Window.innerHTML += ` Window.innerHTML += `
<h2>Compose</h2> <h2>Compose</h2>
<p>Posting in: [Channel]</p>
<textarea style="width: 100%; height: 20em;"></textarea> <textarea style="width: 100%; height: 20em;"></textarea>
<p> <p>
<button onclick="PostNote(this.parentNode.parentNode.querySelector('textarea').value);">Note!</button> <button onclick="PostNote(this.parentNode.parentNode.querySelector('textarea').value);">Note!</button>
@ -211,6 +143,17 @@ function ComposeNote() {
}; };
function PostNote(Text) { function PostNote(Text) {
Obj = ExtrimObj(ApiSchema.Note); Obj = ExtrimObj(ApiSchema.Note);
Obj.Content = Text;
// Find out current profile and destination channel to do a proper net request
};
function ManageSettings() {
MakeWindow().innerHTML = `
* Sources
* Identities
* Data Import/Export
* Cache Persistance
`;
}; };
DoAsync(FetchFeatured, FillFeatured); DoAsync(FetchFeatured, FillFeatured);

45
App/Net.js Normal file
View File

@ -0,0 +1,45 @@
function ApiCall(Data, Proc) {
// Data = {Target: "Friendica", Method: "...", Data: {}, Call: (), CallFine: (), CallFail: ()}
var Req = new XMLHttpRequest();
Req.Proc = Proc;
Req.onloadend = function(){
try {
this.responseJson = JSON.parse(this.responseText);
this.responseLog = this.responseJson;
} catch(Ex) {
this.responseLog = this.responseText;
};
if (Data.Call) {
Data.Call(this);
};
if (IsHttpCodeGood(this.status)) {
LogDebug([this.status, this.responseLog], 'l');
if (Data.CallFine) {
Data.CallFine(this);
};
} else {
LogDebug([this.status, this.responseLog], 'e');
if (Data.CallFail) {
Data.CallFail(this);
};
};
};
if (Data.Target == 'Mastodon') {
Req.open('GET', `${MastodonUrl}/api/v1/${Data.Method}`, true);
} else
if (Data.Target == 'Friendica') {
Req.open('GET', `${FriendicaUrl}/api/${Data.Method}.json`, true);
Req.setRequestHeader('Authorization', `Basic ${btoa(FriendicaCredentials)}`);
};
Req.send();
};
function IsHttpCodeGood(Code) {
Code = String(Code)[0];
if (['1', '2', '3'].includes(Code)) {
return true;
} else
if (['4', '5'].includes(Code)) {
return false;
};
};

View File

@ -3,7 +3,11 @@ function ForceList(Item) {
}; };
function RndId() { function RndId() {
return `${Date.now()}${Math.random()}`; return `${Date.now()}${Math.random() + Math.random()}`;
};
function UrlDomain(Url) {
return Url.split('//')[1].split('/')[0];
}; };
function LogDebug(Data, Status) { function LogDebug(Data, Status) {
@ -112,6 +116,9 @@ function JsonTransformCycleB(TreeOld, SchemaNew, NodeNew, TypeOld) {
Object.keys(KeyOld).forEach(function(KeyObj){ Object.keys(KeyOld).forEach(function(KeyObj){
if (KeyObj === '__Eval__') { if (KeyObj === '__Eval__') {
eval(KeyOld[KeyObj]); eval(KeyOld[KeyObj]);
} else
if (KeyObj === '__EvalSet__') {
TreeNew[KeyNew] = eval(KeyOld[KeyObj]);
}; };
}); });
} else { } else {

View File

@ -5,7 +5,7 @@ from pathlib import Path
os.chdir(os.path.dirname(os.path.abspath(__file__))) os.chdir(os.path.dirname(os.path.abspath(__file__)))
os.makedirs('./Dist', exist_ok=True) os.makedirs('./Dist', exist_ok=True)
os.chdir('./Source') os.chdir('./App')
with open(f'./Friendiiverse.html', 'r') as Base: with open(f'./Friendiiverse.html', 'r') as Base:
Base = Base.read() Base = Base.read()
@ -20,6 +20,9 @@ def FragReplace(Find, Replace, Pattern='*.*'):
File = Prefix + File File = Prefix + File
Base = Base.replace(Find.format(File=File), Frag) Base = Base.replace(Find.format(File=File), Frag)
#BaseNew = []
#BaseNew += Base.split('<script data-build-json="true">')
FragReplace('<link rel="stylesheet" href="{File}"/>', '<style data-source="{File}">{Frag}</style>', '*.css') FragReplace('<link rel="stylesheet" href="{File}"/>', '<style data-source="{File}">{Frag}</style>', '*.css')
FragReplace('<script src="{File}"></script>', '<script data-source="{File}">{Frag}</script>', '*.js') FragReplace('<script src="{File}"></script>', '<script data-source="{File}">{Frag}</script>', '*.js')