Update home, HashyMagnet
This commit is contained in:
parent
281e99f8b3
commit
d7bde824ca
|
@ -44,7 +44,7 @@ Body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.Content {
|
.Content {
|
||||||
background-color: rgba(0,0,0,0.8);
|
background-color: rgba(0,0,0,0.85);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
|
@ -61,7 +61,7 @@ Body {
|
||||||
Max-Width: Fit-Content;
|
Max-Width: Fit-Content;
|
||||||
Margin: Auto;
|
Margin: Auto;
|
||||||
Padding: 16px;
|
Padding: 16px;
|
||||||
Background-Color: RGBA(16,16,16,0.8);
|
Background-Color: RGBA(16,16,16,0.85);
|
||||||
}
|
}
|
||||||
|
|
||||||
.TopBar {
|
.TopBar {
|
||||||
|
@ -76,7 +76,6 @@ Body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.Footer {
|
.Footer {
|
||||||
Background-Color: RGBA(36, 36, 36, 0.8);
|
|
||||||
Position: Fixed;
|
Position: Fixed;
|
||||||
Display: Flex;
|
Display: Flex;
|
||||||
Flex-Direction: Row;
|
Flex-Direction: Row;
|
||||||
|
@ -92,6 +91,19 @@ Body {
|
||||||
Overflow-Y: Hidden;
|
Overflow-Y: Hidden;
|
||||||
White-Space: NoWrap;
|
White-Space: NoWrap;
|
||||||
Z-Index: 1;
|
Z-Index: 1;
|
||||||
|
/* CSS-only scroll shadow effect | Credits to Bartek, <https://stackoverflow.com/questions/44793453/how-do-i-add-a-top-and-bottom-shadow-while-scrolling-but-only-when-needed#comment115950584_44794221> */
|
||||||
|
/*
|
||||||
|
background:
|
||||||
|
linear-gradient(90deg, white 30%, rgba(255, 255, 255, 0)),
|
||||||
|
linear-gradient(90deg, rgba(255, 255, 255, 0), white 70%) 0 100%,
|
||||||
|
radial-gradient(farthest-side at 0% 50%, rgba(0, 0, 0, 0.2), white),
|
||||||
|
radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.2), white) 0 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: top left, top right, top left, top right;
|
||||||
|
background-size: 40px 100%, 40px 100%, 20px 100%, 20px 100%;
|
||||||
|
background-attachment: local, local, scroll, scroll;
|
||||||
|
*/
|
||||||
|
Background-Color: RGBA(36, 36, 36, 0.85);
|
||||||
}
|
}
|
||||||
.Footer > .FooterRight { Margin-Right: 12px; }
|
.Footer > .FooterRight { Margin-Right: 12px; }
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<link href="Bubbles.css" rel="stylesheet">
|
<link href="Bubbles.css" rel="stylesheet">
|
||||||
<link rel="shortcut icon" href="../favicon.png" type="image/x-icon">
|
<link rel="shortcut icon" href="../favicon.png" type="image/x-icon">
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
<style>
|
<style>
|
||||||
Body {
|
Body {
|
||||||
Color: #FFFFFF;
|
Color: #FFFFFF;
|
||||||
Background-Color: #254070;
|
Background-Color: #254070;
|
||||||
|
@ -81,16 +81,14 @@ Button:Disabled {
|
||||||
Background-Color: RGBA(16,16,48,0.5);
|
Background-Color: RGBA(16,16,48,0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Section {
|
.Section { Margin: 4px; }
|
||||||
Margin: 4px;
|
.Smaller { Font-Size: Smaller; }
|
||||||
}
|
.NoWrap { White-Space: NoWrap; }
|
||||||
.NoWrap {
|
|
||||||
White-Space: NoWrap;
|
|
||||||
}
|
|
||||||
.LeftAlign {
|
.LeftAlign {
|
||||||
Text-Align: Left;
|
Text-Align: Left;
|
||||||
Margin-Left: Calc(5% + 8px);
|
Margin-Left: Calc(5% + 8px);
|
||||||
}
|
}
|
||||||
|
.ClickPointer, #TitleTitle { Cursor: Pointer; }
|
||||||
|
|
||||||
#Main {
|
#Main {
|
||||||
Overflow-X: Hidden;
|
Overflow-X: Hidden;
|
||||||
|
@ -103,12 +101,9 @@ Button:Disabled {
|
||||||
Right: 0px;
|
Right: 0px;
|
||||||
Z-Index: 4;
|
Z-Index: 4;
|
||||||
}
|
}
|
||||||
/*
|
#LicenseText {
|
||||||
#Title, #Title > Div {
|
Overflow-Y: Auto;
|
||||||
Max-Width: Fit-Content;
|
|
||||||
Margin: Auto;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
#HomeBtn {
|
#HomeBtn {
|
||||||
Position: Absolute;
|
Position: Absolute;
|
||||||
|
@ -130,17 +125,17 @@ Button:Disabled {
|
||||||
Color: #FFFFFF;
|
Color: #FFFFFF;
|
||||||
Background-Color: #FF0000;
|
Background-Color: #FF0000;
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
.ocean { Overflow: Hidden; }
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="Main">
|
<div id="Main">
|
||||||
<h5 id="HomeBtn">[<a href="..">🔼 Home</a>]</h5>
|
<h5 id="HomeBtn">[<a href="..">🔼 Home</a>]</h5>
|
||||||
<div id="Title" class="Section"><div>
|
<div id="Title" class="Section"><div>
|
||||||
<div id="TitleTitle">
|
<div id="TitleTitle" title="Click for more info!">
|
||||||
<def title="Click for more info!">
|
|
||||||
<h3>HashyMagnet</h3>
|
<h3>HashyMagnet</h3>
|
||||||
<p>Generate a full Bit<span style="Color:#AAFFFF;">Torrent</span> Magnet Link from an Info Hash...</p>
|
<p>Generate a full Bit<span style="Color:#AAFFFF;">Torrent</span> Magnet Link from an Info Hash...</p>
|
||||||
</def>
|
|
||||||
</div>
|
</div>
|
||||||
<noscript><p>
|
<noscript><p>
|
||||||
This is an actual app, not a badly-made website.
|
This is an actual app, not a badly-made website.
|
||||||
|
@ -153,7 +148,7 @@ Button:Disabled {
|
||||||
<h4>Info</h4>
|
<h4>Info</h4>
|
||||||
<p>With this app you can generate full <a href="https://en.m.wikipedia.org/wiki/Magnet_URI_scheme" target="_blank" rel="noopener nofollow">BitTorrent Magnet links</a>, complete with trackers, from a simple Info Hash.</p>
|
<p>With this app you can generate full <a href="https://en.m.wikipedia.org/wiki/Magnet_URI_scheme" target="_blank" rel="noopener nofollow">BitTorrent Magnet links</a>, complete with trackers, from a simple Info Hash.</p>
|
||||||
<p>You can input your own list of trackers, or you can use the one that's autogenerated by the app from up-to-date lists.</p>
|
<p>You can input your own list of trackers, or you can use the one that's autogenerated by the app from up-to-date lists.</p>
|
||||||
<p>Last updated: 2022-11-29.</p>
|
<p class="Smaller ClickPointer" onclick="alert('{{ Changelog }}\n\n' + Changelog);">Last updated on <span id="LastUpdatedDate"></span>.</p>
|
||||||
<h4>Special Thanks and Credits</h4>
|
<h4>Special Thanks and Credits</h4>
|
||||||
<p>
|
<p>
|
||||||
Tracker lists providers:
|
Tracker lists providers:
|
||||||
|
@ -167,8 +162,8 @@ Button:Disabled {
|
||||||
<br>
|
<br>
|
||||||
<a href="https://codinhood.com/micro/animate-octocat-sprite-css" target="_blank" rel="noopener nofollow">https://codinhood.com/micro/animate-octocat-sprite-css</a></p>
|
<a href="https://codinhood.com/micro/animate-octocat-sprite-css" target="_blank" rel="noopener nofollow">https://codinhood.com/micro/animate-octocat-sprite-css</a></p>
|
||||||
<h4>License</h4>
|
<h4>License</h4>
|
||||||
<pre>HashyMagnet
|
<pre id="LicenseText">HashyMagnet
|
||||||
Copyright (C) 2022, OctoSpacc
|
Copyright (C) 2022-2023, <a href="https://hub.octt.eu.org">OctoSpacc</a>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
@ -209,7 +204,14 @@ along with this program. If not, see <a href="https://www.gnu.org/licenses" targ
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
<div class="ocean"><div class="bubble bubble-1"></div><div class="bubble bubble-2"></div><div class="bubble bubble-3"></div><div class="bubble bubble-4"></div><div class="bubble bubble-5"></div><div class="bubble bubble-6"></div><div class="bubble bubble-7"></div><div class="bubble bubble-8"></div><div class="bubble bubble-9"></div><div class="bubble bubble-10"></div><div class="bubble bubble-11"></div></div>
|
<div class="ocean"><div class="bubble bubble-1"></div><div class="bubble bubble-2"></div><div class="bubble bubble-3"></div><div class="bubble bubble-4"></div><div class="bubble bubble-5"></div><div class="bubble bubble-6"></div><div class="bubble bubble-7"></div><div class="bubble bubble-8"></div><div class="bubble bubble-9"></div><div class="bubble bubble-10"></div><div class="bubble bubble-11"></div></div>
|
||||||
<script>
|
<script>
|
||||||
|
// https://stackoverflow.com/a/63958411
|
||||||
|
String.prototype.replaceAllTxt = function replaceAll(search, replace) {
|
||||||
|
return this.split(search).join(replace);
|
||||||
|
};
|
||||||
|
|
||||||
|
const OnInputChangePaste = ['onchange', 'oninput', 'onpaste'];
|
||||||
|
|
||||||
var Generated = false;
|
var Generated = false;
|
||||||
var Trackers = [],
|
var Trackers = [],
|
||||||
FetchTrackers = [];
|
FetchTrackers = [];
|
||||||
|
@ -223,8 +225,8 @@ function SplitLines(Text) {
|
||||||
if (Text == "") {
|
if (Text == "") {
|
||||||
return [];
|
return [];
|
||||||
} else {
|
} else {
|
||||||
return Text.trim().replaceAll("\r","").replace(/\n\s*\n/g,"\n").split("\n")
|
return Text.trim().replaceAllTxt('\r', '').replace(/\n\s*\n/g, '\n').split('\n');
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function DoFetchTrackers() {
|
async function DoFetchTrackers() {
|
||||||
|
@ -238,7 +240,7 @@ async function DoFetchTrackers() {
|
||||||
|
|
||||||
function WriteFetchTrackers() {
|
function WriteFetchTrackers() {
|
||||||
for (let i = 0; i < FetchTrackers.length; i++) {
|
for (let i = 0; i < FetchTrackers.length; i++) {
|
||||||
TrackersArea.value += FetchTrackers[i] + "\n\n";
|
TrackersArea.value += FetchTrackers[i] + '\n\n';
|
||||||
}
|
}
|
||||||
StoreTrackers();
|
StoreTrackers();
|
||||||
DoRedraw();
|
DoRedraw();
|
||||||
|
@ -254,48 +256,36 @@ async function CallWriteFetchTrackers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateBtn.onclick = function() {
|
GenerateBtn.onclick = function() {
|
||||||
TextBox.value = TextBox.value.substr(TextBox.value.lastIndexOf(":")+1);
|
['magnet:', '?xt=urn:', 'btih:'].forEach(function(i) {
|
||||||
TextBox.value = "magnet:?xt=urn:btih:" + TextBox.value;
|
if (TextBox.value.toLowerCase().startsWith(i)) {
|
||||||
|
TextBox.value = TextBox.value.substring(i.length);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
TextBox.value = 'magnet:?xt=urn:btih:' + TextBox.value;
|
||||||
for (let i = 0; i < Trackers.length; i++) {
|
for (let i = 0; i < Trackers.length; i++) {
|
||||||
TextBox.value += "&tr=" + encodeURIComponent(Trackers[i]);
|
TextBox.value += '&tr=' + encodeURIComponent(Trackers[i]);
|
||||||
}
|
};
|
||||||
Generated = true;
|
Generated = true;
|
||||||
DoRedraw();
|
DoRedraw();
|
||||||
};
|
};
|
||||||
|
|
||||||
function DoRedraw() {
|
function DoRedraw() {
|
||||||
TextBox.style = "";
|
TextBox.style = '';
|
||||||
let TextBoxWidth = TextBox.offsetWidth;
|
let TextBoxWidth = TextBox.offsetWidth;
|
||||||
if (Generated) {
|
if (Generated) {
|
||||||
TextBox.disabled = true;
|
TextBox.disabled = GenerateBtn.disabled = GenerateBtn.hidden = true;
|
||||||
GenerateBtn.disabled = true;
|
TextBox.style = 'Width:' + (TextBoxWidth - ResetBtn.offsetWidth - 12) + 'px;'
|
||||||
GenerateBtn.hidden = true;
|
ResetBtn.hidden = CopyBtn.hidden = OpenBtn.hidden = false;
|
||||||
ResetBtn.hidden = false;
|
|
||||||
TextBox.style = "Width:" + (TextBoxWidth - ResetBtn.offsetWidth - 12) + "px;"
|
|
||||||
CopyBtn.hidden = false;
|
|
||||||
OpenBtn.hidden = false;
|
|
||||||
} else {
|
} else {
|
||||||
TextBox.disabled = false;
|
TextBox.disabled = GenerateBtn.disabled = GenerateBtn.hidden = false;
|
||||||
GenerateBtn.disabled = false;
|
ResetBtn.hidden = CopyBtn.hidden = OpenBtn.hidden = true;
|
||||||
GenerateBtn.hidden = false;
|
};
|
||||||
ResetBtn.hidden = true;
|
GenerateBtn.disabled = !TextBox.value;
|
||||||
CopyBtn.hidden = true;
|
TrackersBtn.textContent = (TrackersArea.value ? '🗑️ Clear' : '🔄 Restore');
|
||||||
OpenBtn.hidden = true;
|
|
||||||
}
|
|
||||||
if (TextBox.value) {
|
|
||||||
GenerateBtn.disabled = false;
|
|
||||||
} else {
|
|
||||||
GenerateBtn.disabled = true;
|
|
||||||
}
|
|
||||||
if (TrackersArea.value) {
|
|
||||||
TrackersBtn.textContent = "🗑️ Clear";
|
|
||||||
} else {
|
|
||||||
TrackersBtn.textContent = "🔄 Restore";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetBtn.onclick = function() {
|
ResetBtn.onclick = function() {
|
||||||
TextBox.value = "";
|
TextBox.value = '';
|
||||||
Generated = false;
|
Generated = false;
|
||||||
DoRedraw();
|
DoRedraw();
|
||||||
};
|
};
|
||||||
|
@ -310,30 +300,29 @@ OpenBtn.onclick = function() {
|
||||||
|
|
||||||
TrackersBtn.onclick = function() {
|
TrackersBtn.onclick = function() {
|
||||||
if (TrackersArea.value) {
|
if (TrackersArea.value) {
|
||||||
TrackersArea.value = "";
|
TrackersArea.value = '';
|
||||||
StoreTrackers();
|
StoreTrackers();
|
||||||
} else {
|
} else {
|
||||||
WriteFetchTrackers();
|
WriteFetchTrackers();
|
||||||
}
|
};
|
||||||
DoRedraw();
|
DoRedraw();
|
||||||
};
|
};
|
||||||
|
|
||||||
function TrackersAreaOnChange() {
|
OnInputChangePaste.forEach(function(i) {
|
||||||
|
TrackersArea[i] = function TrackersAreaOnChange() {
|
||||||
StoreTrackers();
|
StoreTrackers();
|
||||||
DoRedraw();
|
DoRedraw();
|
||||||
}
|
};
|
||||||
TrackersArea.onchange = TrackersAreaOnChange;
|
});
|
||||||
TrackersArea.oninput = TrackersAreaOnChange;
|
|
||||||
TrackersArea.onpaste = TrackersAreaOnChange;
|
|
||||||
|
|
||||||
TextBox.onkeydown = function(e) {
|
TextBox.onkeydown = function(e) {
|
||||||
if (e.keyCode == 13 && !Generated) {
|
if (e.keyCode == 13 && !Generated) {
|
||||||
GenerateBtn.click();
|
GenerateBtn.click();
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
TextBox.onchange = DoRedraw;
|
OnInputChangePaste.forEach(function(i) {
|
||||||
TextBox.oninput = DoRedraw;
|
TextBox[i] = DoRedraw;
|
||||||
TextBox.onpaste = DoRedraw;
|
});
|
||||||
|
|
||||||
window.onresize = DoRedraw;
|
window.onresize = DoRedraw;
|
||||||
|
|
||||||
|
@ -342,10 +331,18 @@ TitleTitle.onclick = function() {
|
||||||
Info.hidden = !Info.hidden;
|
Info.hidden = !Info.hidden;
|
||||||
};
|
};
|
||||||
|
|
||||||
TextBox.value = new URLSearchParams(window.location.hash).get("#Hash");
|
TextBox.value = new URLSearchParams(window.location.hash).get('#Hash');
|
||||||
|
|
||||||
DoRedraw();
|
DoRedraw();
|
||||||
CallWriteFetchTrackers();
|
CallWriteFetchTrackers();
|
||||||
</script>
|
|
||||||
|
const Changelog = `\
|
||||||
|
[ 2023-01-18 ]
|
||||||
|
- Fix handling of torrent hash input
|
||||||
|
- Improve support for older browsers
|
||||||
|
- Improve minor UI/UX aspects
|
||||||
|
`;
|
||||||
|
LastUpdatedDate.innerHTML = Changelog.split('\n')[0].substring(2, 12);
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"short_name": "HashyMagnet",
|
||||||
|
"name": "HashyMagnet",
|
||||||
|
"description": "Generate a full BitTorrent Magnet Link from an Info Hash",
|
||||||
|
"credits": "App icon is 🧲 emoji from Twemoji - CC-BY 4.0, <https://twemoji.twitter.com>",
|
||||||
|
"start_url": "https://hub.octt.eu.org/HashyMagnet",
|
||||||
|
"scope": "https://hub.octt.eu.org/HashyMagnet",
|
||||||
|
"display": "standalone",
|
||||||
|
"theme_color": "#2980b9",
|
||||||
|
"background_color": "#2980b9",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "https://cdn.jsdelivr.net/gh/octospacc/twemoji-astonishing@gh-pages/i/1f9f2.svg",
|
||||||
|
"type": "image/svg+xml",
|
||||||
|
"sizes": "512x512"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -55,7 +55,7 @@
|
||||||
<span> </span>
|
<span> </span>
|
||||||
<a rel="me" href="https://botsin.space/@octtpz">-> pezziposting 🦜</a>
|
<a rel="me" href="https://botsin.space/@octtpz">-> pezziposting 🦜</a>
|
||||||
<span> </span>
|
<span> </span>
|
||||||
<a rel="me" href="https://spacc.xyz">-> Spacc ⛏️</a>
|
<a href="https://spacc-inc.github.io">-> Spacc ⛏️</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in New Issue