Update home, HashyMagnet
This commit is contained in:
parent
281e99f8b3
commit
d7bde824ca
|
@ -44,7 +44,7 @@ Body {
|
|||
}
|
||||
|
||||
.Content {
|
||||
background-color: rgba(0,0,0,0.8);
|
||||
background-color: rgba(0,0,0,0.85);
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
|
@ -61,7 +61,7 @@ Body {
|
|||
Max-Width: Fit-Content;
|
||||
Margin: Auto;
|
||||
Padding: 16px;
|
||||
Background-Color: RGBA(16,16,16,0.8);
|
||||
Background-Color: RGBA(16,16,16,0.85);
|
||||
}
|
||||
|
||||
.TopBar {
|
||||
|
@ -76,7 +76,6 @@ Body {
|
|||
}
|
||||
|
||||
.Footer {
|
||||
Background-Color: RGBA(36, 36, 36, 0.8);
|
||||
Position: Fixed;
|
||||
Display: Flex;
|
||||
Flex-Direction: Row;
|
||||
|
@ -92,6 +91,19 @@ Body {
|
|||
Overflow-Y: Hidden;
|
||||
White-Space: NoWrap;
|
||||
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; }
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<link href="Bubbles.css" rel="stylesheet">
|
||||
<link rel="shortcut icon" href="../favicon.png" type="image/x-icon">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<style>
|
||||
<style>
|
||||
Body {
|
||||
Color: #FFFFFF;
|
||||
Background-Color: #254070;
|
||||
|
@ -81,16 +81,14 @@ Button:Disabled {
|
|||
Background-Color: RGBA(16,16,48,0.5);
|
||||
}
|
||||
|
||||
.Section {
|
||||
Margin: 4px;
|
||||
}
|
||||
.NoWrap {
|
||||
White-Space: NoWrap;
|
||||
}
|
||||
.Section { Margin: 4px; }
|
||||
.Smaller { Font-Size: Smaller; }
|
||||
.NoWrap { White-Space: NoWrap; }
|
||||
.LeftAlign {
|
||||
Text-Align: Left;
|
||||
Margin-Left: Calc(5% + 8px);
|
||||
}
|
||||
.ClickPointer, #TitleTitle { Cursor: Pointer; }
|
||||
|
||||
#Main {
|
||||
Overflow-X: Hidden;
|
||||
|
@ -103,12 +101,9 @@ Button:Disabled {
|
|||
Right: 0px;
|
||||
Z-Index: 4;
|
||||
}
|
||||
/*
|
||||
#Title, #Title > Div {
|
||||
Max-Width: Fit-Content;
|
||||
Margin: Auto;
|
||||
#LicenseText {
|
||||
Overflow-Y: Auto;
|
||||
}
|
||||
*/
|
||||
|
||||
#HomeBtn {
|
||||
Position: Absolute;
|
||||
|
@ -130,17 +125,17 @@ Button:Disabled {
|
|||
Color: #FFFFFF;
|
||||
Background-Color: #FF0000;
|
||||
}
|
||||
</style>
|
||||
|
||||
.ocean { Overflow: Hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="Main">
|
||||
<h5 id="HomeBtn">[<a href="..">🔼 Home</a>]</h5>
|
||||
<div id="Title" class="Section"><div>
|
||||
<div id="TitleTitle">
|
||||
<def title="Click for more info!">
|
||||
<div id="TitleTitle" title="Click for more info!">
|
||||
<h3>HashyMagnet</h3>
|
||||
<p>Generate a full Bit<span style="Color:#AAFFFF;">Torrent</span> Magnet Link from an Info Hash...</p>
|
||||
</def>
|
||||
</div>
|
||||
<noscript><p>
|
||||
This is an actual app, not a badly-made website.
|
||||
|
@ -153,7 +148,7 @@ Button:Disabled {
|
|||
<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>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>
|
||||
<p>
|
||||
Tracker lists providers:
|
||||
|
@ -167,8 +162,8 @@ Button:Disabled {
|
|||
<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>
|
||||
<h4>License</h4>
|
||||
<pre>HashyMagnet
|
||||
Copyright (C) 2022, OctoSpacc
|
||||
<pre id="LicenseText">HashyMagnet
|
||||
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
|
||||
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>
|
||||
</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 Trackers = [],
|
||||
FetchTrackers = [];
|
||||
|
@ -223,8 +225,8 @@ function SplitLines(Text) {
|
|||
if (Text == "") {
|
||||
return [];
|
||||
} 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() {
|
||||
|
@ -238,7 +240,7 @@ async function DoFetchTrackers() {
|
|||
|
||||
function WriteFetchTrackers() {
|
||||
for (let i = 0; i < FetchTrackers.length; i++) {
|
||||
TrackersArea.value += FetchTrackers[i] + "\n\n";
|
||||
TrackersArea.value += FetchTrackers[i] + '\n\n';
|
||||
}
|
||||
StoreTrackers();
|
||||
DoRedraw();
|
||||
|
@ -254,48 +256,36 @@ async function CallWriteFetchTrackers() {
|
|||
}
|
||||
|
||||
GenerateBtn.onclick = function() {
|
||||
TextBox.value = TextBox.value.substr(TextBox.value.lastIndexOf(":")+1);
|
||||
TextBox.value = "magnet:?xt=urn:btih:" + TextBox.value;
|
||||
['magnet:', '?xt=urn:', 'btih:'].forEach(function(i) {
|
||||
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++) {
|
||||
TextBox.value += "&tr=" + encodeURIComponent(Trackers[i]);
|
||||
}
|
||||
TextBox.value += '&tr=' + encodeURIComponent(Trackers[i]);
|
||||
};
|
||||
Generated = true;
|
||||
DoRedraw();
|
||||
};
|
||||
|
||||
function DoRedraw() {
|
||||
TextBox.style = "";
|
||||
TextBox.style = '';
|
||||
let TextBoxWidth = TextBox.offsetWidth;
|
||||
if (Generated) {
|
||||
TextBox.disabled = true;
|
||||
GenerateBtn.disabled = true;
|
||||
GenerateBtn.hidden = true;
|
||||
ResetBtn.hidden = false;
|
||||
TextBox.style = "Width:" + (TextBoxWidth - ResetBtn.offsetWidth - 12) + "px;"
|
||||
CopyBtn.hidden = false;
|
||||
OpenBtn.hidden = false;
|
||||
TextBox.disabled = GenerateBtn.disabled = GenerateBtn.hidden = true;
|
||||
TextBox.style = 'Width:' + (TextBoxWidth - ResetBtn.offsetWidth - 12) + 'px;'
|
||||
ResetBtn.hidden = CopyBtn.hidden = OpenBtn.hidden = false;
|
||||
} else {
|
||||
TextBox.disabled = false;
|
||||
GenerateBtn.disabled = false;
|
||||
GenerateBtn.hidden = false;
|
||||
ResetBtn.hidden = true;
|
||||
CopyBtn.hidden = true;
|
||||
OpenBtn.hidden = true;
|
||||
}
|
||||
if (TextBox.value) {
|
||||
GenerateBtn.disabled = false;
|
||||
} else {
|
||||
GenerateBtn.disabled = true;
|
||||
}
|
||||
if (TrackersArea.value) {
|
||||
TrackersBtn.textContent = "🗑️ Clear";
|
||||
} else {
|
||||
TrackersBtn.textContent = "🔄 Restore";
|
||||
}
|
||||
TextBox.disabled = GenerateBtn.disabled = GenerateBtn.hidden = false;
|
||||
ResetBtn.hidden = CopyBtn.hidden = OpenBtn.hidden = true;
|
||||
};
|
||||
GenerateBtn.disabled = !TextBox.value;
|
||||
TrackersBtn.textContent = (TrackersArea.value ? '🗑️ Clear' : '🔄 Restore');
|
||||
}
|
||||
|
||||
ResetBtn.onclick = function() {
|
||||
TextBox.value = "";
|
||||
TextBox.value = '';
|
||||
Generated = false;
|
||||
DoRedraw();
|
||||
};
|
||||
|
@ -310,30 +300,29 @@ OpenBtn.onclick = function() {
|
|||
|
||||
TrackersBtn.onclick = function() {
|
||||
if (TrackersArea.value) {
|
||||
TrackersArea.value = "";
|
||||
TrackersArea.value = '';
|
||||
StoreTrackers();
|
||||
} else {
|
||||
WriteFetchTrackers();
|
||||
}
|
||||
};
|
||||
DoRedraw();
|
||||
};
|
||||
|
||||
function TrackersAreaOnChange() {
|
||||
OnInputChangePaste.forEach(function(i) {
|
||||
TrackersArea[i] = function TrackersAreaOnChange() {
|
||||
StoreTrackers();
|
||||
DoRedraw();
|
||||
}
|
||||
TrackersArea.onchange = TrackersAreaOnChange;
|
||||
TrackersArea.oninput = TrackersAreaOnChange;
|
||||
TrackersArea.onpaste = TrackersAreaOnChange;
|
||||
};
|
||||
});
|
||||
|
||||
TextBox.onkeydown = function(e) {
|
||||
if (e.keyCode == 13 && !Generated) {
|
||||
GenerateBtn.click();
|
||||
}
|
||||
};
|
||||
};
|
||||
TextBox.onchange = DoRedraw;
|
||||
TextBox.oninput = DoRedraw;
|
||||
TextBox.onpaste = DoRedraw;
|
||||
OnInputChangePaste.forEach(function(i) {
|
||||
TextBox[i] = DoRedraw;
|
||||
});
|
||||
|
||||
window.onresize = DoRedraw;
|
||||
|
||||
|
@ -342,10 +331,18 @@ TitleTitle.onclick = function() {
|
|||
Info.hidden = !Info.hidden;
|
||||
};
|
||||
|
||||
TextBox.value = new URLSearchParams(window.location.hash).get("#Hash");
|
||||
TextBox.value = new URLSearchParams(window.location.hash).get('#Hash');
|
||||
|
||||
DoRedraw();
|
||||
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>
|
||||
</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>
|
||||
<a rel="me" href="https://botsin.space/@octtpz">-> pezziposting 🦜</a>
|
||||
<span> </span>
|
||||
<a rel="me" href="https://spacc.xyz">-> Spacc ⛏️</a>
|
||||
<a href="https://spacc-inc.github.io">-> Spacc ⛏️</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
|
|
Loading…
Reference in New Issue