+
+}
+
func Components.Subscribe(tytd,id)
{
var bell = tytd.GetSubscriptionBell(id);
diff --git a/Tesses.YouTubeDownloader.Server/src/main.tcross b/Tesses.YouTubeDownloader.Server/src/main.tcross
index e842feb..be3cafa 100644
--- a/Tesses.YouTubeDownloader.Server/src/main.tcross
+++ b/Tesses.YouTubeDownloader.Server/src/main.tcross
@@ -540,16 +540,30 @@ class TYTDApp {
}
return false;
}
- else if(ctx.Path == "/api/v1/progress_ex.json")
+ else if(ctx.Path == "/api/v1/progress_ex" || ctx.Path == "/api/v1/progress_ex.json")
{
ctx.WithMimeType("application/json").SendJson(this.TYTD.GetProgressEx());
return true;
}
- else if(ctx.Path == "/api/v1/progress.json")
+ else if(ctx.Path == "/api/v1/progress" || ctx.Path == "/api/v1/progress.json")
{
ctx.WithMimeType("application/json").SendJson(this.TYTD.GetProgress());
return true;
}
+ else if(ctx.Path == "/api/v1/server")
+ {
+ ctx.WithMimeType("application/json").SendJson(
+ {
+ Service = "tytd2025",
+ TYTD = {
+ CrossLangVersion = VM.RuntimeVersion.ToString(),
+ TYTDTag = this.TYTD.Config.TYTDTag,
+ DownloaderVersion = Resolution.getResolutions.File.Version.ToString()
+ }
+ }
+ );
+ return true;
+ }
else if(ctx.Path == "/api/v1/add")
{
if(ctx.Method=="POST")
@@ -564,14 +578,14 @@ class TYTDApp {
return true;
}
}
- else if(ctx.Path == "/api/v1/video.json")
+ else if(ctx.Path == "/api/v1/video" || ctx.Path == "/api/v1/video.json")
{
var id = ctx.QueryParams.TryGetFirst("v");
if(TypeOf(id)!="String") id = "";
ctx.WithMimeType("application/json").SendJson(this.TYTD.GetVideo(id));
return true;
}
- else if(ctx.Path == "/api/v1/playlist.json")
+ else if(ctx.Path == "/api/v1/playlist" || ctx.Path == "/api/v1/playlist.json")
{
var id = ctx.QueryParams.TryGetFirst("id");
var page = ctx.QueryParams.TryGetFirstInt("page");
@@ -582,7 +596,7 @@ class TYTDApp {
ctx.WithMimeType("application/json").SendJson(this.TYTD.GetPlaylistContents(id,page-1,count));
return true;
}
- else if(ctx.Path == "/api/v1/channel.json")
+ else if(ctx.Path == "/api/v1/channel" || ctx.Path == "/api/v1/channel.json")
{
var id = ctx.QueryParams.TryGetFirst("id");
var page = ctx.QueryParams.TryGetFirstInt("page");
@@ -593,9 +607,9 @@ class TYTDApp {
ctx.WithMimeType("application/json").SendJson(this.TYTD.GetChannelContents(id,page-1,count));
return true;
}
- else if(ctx.Path == "/api/v1/queue.json")
+ else if(ctx.Path == "/api/v1/queue" || ctx.Path == "/api/v1/queue.json")
{
- if(ctx.Method == "GET")
+ if(ctx.Method == "GET" || ctx.Method == "HEAD")
{
var page = ctx.QueryParams.TryGetFirstInt("page");
var count = ctx.QueryParams.TryGetFirstInt("count");
@@ -608,7 +622,33 @@ class TYTDApp {
return true;
}
}
- else if(ctx.Path == "/api/v1/downloads.json")
+ else if(ctx.Path == "/api/v1/subscriptions")
+ {
+ if(ctx.Method == "GET" || ctx.Method == "HEAD")
+ {
+ ctx.WithMimeType("application/json").SendJson(this.TYTD.GetSubscriptions());
+ }
+ else if(ctx.Method == "POST")
+ {
+ const json = ctx.ParseJson();
+
+ // bell: null => unsubscribe; absent => default to BellLow
+
+ const bell = json.bell == undefined ? SubscriptionBell.BellLow : json.bell;
+
+ const id = json.id ?? "";
+
+
+
+ this.TYTD.SetSubscriptionBell(id, bell);
+
+
+ ctx.StatusCode = 204;
+ ctx.WriteHeaders();
+ return true;
+ }
+ }
+ else if(ctx.Path == "/api/v1/downloads" || ctx.Path == "/api/v1/downloads.json")
{
var q = ctx.QueryParams.TryGetFirst("q");
var type = ctx.QueryParams.TryGetFirst("type");
@@ -661,7 +701,7 @@ class TYTDApp {
}
}
- else if(ctx.Path == "/api/v1/manifest.json")
+ else if(ctx.Path == "/api/v1/manifest" || ctx.Path == "/api/v1/manifest.json")
{
const v = ctx.QueryParams.TryGetFirst("v");
if(TypeIsString(v))
@@ -684,7 +724,7 @@ class TYTDApp {
name=
*/
- if(ctx.Method == "GET")
+ if(ctx.Method == "GET" || ctx.Method == "HEAD")
{
var name = ctx.QueryParams.TryGetFirst("name");
if(TypeOf(name) == "String")
@@ -716,7 +756,23 @@ class TYTDApp {
{
var idHas = TypeOf(j.id) == "String" && j.id != "";
var descHas = TypeOf(j.description) == "String" && j.description != "";
- if(idHas && descHas)
+ var mode = TypeIsString(j.mode) ? j.mode : "add";
+
+ if(mode == "delete")
+ {
+ if(descHas)
+ {
+ ctx.WithMimeType("application/json").SendJson({success=false,reason="You provided a description which doesn't make sense when deleting something."});
+ }
+ else if(idHas)
+ {
+ this.TYTD.RemoveFromPersonalList(j.name,j.id);
+ }
+ else {
+ this.TYTD.RemovePersonalList(j.name);
+ }
+ }
+ else if(idHas && descHas)
{
ctx.WithMimeType("application/json").SendJson({success=false,reason="You provided both a description (to set the list description) and id (to add a item) (you can only provide one)"});
}
@@ -765,12 +821,17 @@ class TYTDApp {
}
}
+ else if(ctx.Path == "/subscriptions")
+ {
+ ctx.WithMimeType("text/html").SendText(Pages.Subscriptions(this.TYTD));
+ return true;
+ }
else if(ctx.Path == "/subscribe")
{
- var id = ctx.QueryParams.TryGetFirst("id");
- var bell = ctx.QueryParams.TryGetFirst("bell");
- var type = ctx.QueryParams.TryGetFirst("type");
-
+ var id = ctx.BodyParams.TryGetFirst("id");
+ var bell = ctx.BodyParams.TryGetFirst("bell");
+ var type = ctx.BodyParams.TryGetFirst("type");
+
switch(type)
{
@@ -781,9 +842,17 @@ class TYTDApp {
case "unsubscribe":
this.TYTD.SetSubscriptionBell(id, null);
break;
+ case "unsubscribe-subscriptions-page":
+ this.TYTD.SetSubscriptionBell(id, null);
+ ctx.WithHeader("HX-Location", "/subscriptions").WriteHeaders();
+ return true;
case "bell":
this.TYTD.SetSubscriptionBell(id, bell);
break;
+ case "bell-subscriptions-page":
+ this.TYTD.SetSubscriptionBell(id, bell);
+ ctx.WithMimeType("text/html").SendText(Components.SubscribePageBell(this.TYTD,id));
+ return true;
}
ctx.WithMimeType("text/html").SendText(Components.Subscribe(this.TYTD,id));
return true;
@@ -797,7 +866,7 @@ class TYTDApp {
else if(ctx.Path == "/edit-personal-description")
{
var name = ctx.QueryParams.TryGetFirst("name");
- if(ctx.Method == "GET")
+ if(ctx.Method == "GET" || ctx.Method == "HEAD")
{
ctx.WithMimeType("text/html").SendText(Components.PersonalListDescription(this.TYTD,name,true));
return true;
@@ -968,7 +1037,7 @@ class TYTDApp {
else if(ctx.Path == "/watch_videos")
{
- if(ctx.Method=="GET")
+ if(ctx.Method=="GET" || ctx.Method == "HEAD")
{
const video_ids = ctx.QueryParams.TryGetFirst("video_ids");
@@ -1261,4 +1330,4 @@ func main(args)
Net.Http.ListenSimpleWithLoop(res,3255);
res.Close();
return 0;
-}
\ No newline at end of file
+}
diff --git a/Tesses.YouTubeDownloader.Server/src/pages/admin.tcross b/Tesses.YouTubeDownloader.Server/src/pages/admin.tcross
index d5694d8..304a666 100644
--- a/Tesses.YouTubeDownloader.Server/src/pages/admin.tcross
+++ b/Tesses.YouTubeDownloader.Server/src/pages/admin.tcross
@@ -72,5 +72,5 @@ func Pages.Admin(tytd,ctx)
;
- return Components.Shell("Admin Settings",html ,4);
+ return Components.Shell("Admin Settings",html ,5);
}
\ No newline at end of file
diff --git a/Tesses.YouTubeDownloader.Server/src/pages/api.tcross b/Tesses.YouTubeDownloader.Server/src/pages/api.tcross
index 9607355..15356bb 100644
--- a/Tesses.YouTubeDownloader.Server/src/pages/api.tcross
+++ b/Tesses.YouTubeDownloader.Server/src/pages/api.tcross
@@ -8,5 +8,5 @@ func Pages.Api()
;
- return Components.Shell("Api",html,5);
+ return Components.Shell("Api",html,6);
}
\ No newline at end of file
diff --git a/Tesses.YouTubeDownloader.Server/src/pages/api/api-v1.tcross b/Tesses.YouTubeDownloader.Server/src/pages/api/api-v1.tcross
index 1375cfd..02577d0 100644
--- a/Tesses.YouTubeDownloader.Server/src/pages/api/api-v1.tcross
+++ b/Tesses.YouTubeDownloader.Server/src/pages/api/api-v1.tcross
@@ -21,7 +21,7 @@ func Pages.ApiV1()
;
- return Components.Shell("Api V1",html,5);
+ return Components.Shell("Api V1",html,6);
}
var apiv1_routes = Json.Decode(embed("apiv1_routes.json").ToString());
diff --git a/Tesses.YouTubeDownloader.Server/src/pages/changepassword.tcross b/Tesses.YouTubeDownloader.Server/src/pages/changepassword.tcross
index 98eb16b..e0ce608 100644
--- a/Tesses.YouTubeDownloader.Server/src/pages/changepassword.tcross
+++ b/Tesses.YouTubeDownloader.Server/src/pages/changepassword.tcross
@@ -45,5 +45,5 @@ const html = ;
- return Components.Shell("Change your password",html,4);
+ return Components.Shell("Change your password",html,5);
}
\ No newline at end of file
diff --git a/Tesses.YouTubeDownloader.Server/src/pages/channel/info.tcross b/Tesses.YouTubeDownloader.Server/src/pages/channel/info.tcross
index 4049c44..48a5cd7 100644
--- a/Tesses.YouTubeDownloader.Server/src/pages/channel/info.tcross
+++ b/Tesses.YouTubeDownloader.Server/src/pages/channel/info.tcross
@@ -8,13 +8,21 @@ func Pages.ChannelInfo(tytd,ctx)
var html =
Could not find channel
;
var title = "N/A";
- if(TypeOf(id) == "String")
- {
id = TYTD.GetChannelId(id);
+ if(TypeIsString(id))
+ {
+
+
+
var res = tytd.GetChannelContents(id,page,20);
+
html =