From e9b194217ad0c27ae05657bd2d874fab1772fb8a Mon Sep 17 00:00:00 2001 From: Pablo Ferreiro Date: Sun, 2 Jan 2022 00:06:00 +0100 Subject: [PATCH] Hash system and controls inside player --- .env | 0 .gitignore | 1 + README.md | 4 ++ index.php | 22 ++++---- scripts/user.js | 118 ++++++++++++++++++++++++++++++++++--------- styles/user.css | 6 --- views/home.html | 27 ++++++---- views/user.blade.php | 44 +++++++++------- 8 files changed, 151 insertions(+), 71 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index e69de29..0000000 diff --git a/.gitignore b/.gitignore index 3b9f708..a33b9a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/.env /.vscode /vendor /cache/views/* diff --git a/README.md b/README.md index a2d9ee8..beae93b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # TikTok alternative Frontend +Use Tiktok using an alternative frontend, inspired by Nitter. ## Installation Clone the repository and fetch the requiered external packages with: @@ -14,6 +15,9 @@ php -S localhost:8080 ## Known issues * Right now there is an error when trying to fetch the desired user, there is already a pull request not merged yet fixing this issue on the TikTokApi repo, you can check it out [here](https://github.com/ssovit/TikTok-API-PHP/pull/43) +## TODO +* Allow searching for just one video using the ID + ## Credits * [TikTok-API-PHP](https://github.com/ssovit/TikTok-API-PHP) * [Leaf Framework](https://github.com/leafsphp/leaf) diff --git a/index.php b/index.php index 9cdf157..75c7672 100644 --- a/index.php +++ b/index.php @@ -9,7 +9,17 @@ $app->get('/', function () use ($app) { $app->response()->page('./views/home.html'); }); -$app->get("/users/{user}", function (string $username) { +$app->get('/stream', function () { + if (!isset($_GET['url'])) { + die('You need to send a url!'); + } + + // Start streamer + $streamer = new \Sovit\TikTok\Stream(); + $streamer->stream($_GET['url']); +}); + +$app->get("/@([^/]+)", function (string $username) { $cursor = 0; if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) { $cursor = (int) $_GET['cursor']; @@ -24,14 +34,4 @@ $app->get("/users/{user}", function (string $username) { } }); -$app->get('/stream', function () { - if (!isset($_GET['url'])) { - die('You need to send a url!'); - } - - // Start streamer - $streamer = new \Sovit\TikTok\Stream(); - $streamer->stream($_GET['url']); -}); - $app->run(); diff --git a/scripts/user.js b/scripts/user.js index 9287655..7d7375d 100644 --- a/scripts/user.js +++ b/scripts/user.js @@ -3,38 +3,108 @@ const item_title = document.getElementById('item_title') const audio = document.getElementById('audio') const audio_title = document.getElementById('audio_title') const modal = document.getElementById('modal') -const download = document.getElementById('download_button') +const download_button = document.getElementById('download_button') -const showModal = (e) => { - video.src = e.target.dataset.video_url - video.width = e.target.dataset.video_width - video.height = e.target.dataset.video_height - item_title.innerText = e.target.dataset.desc - download.href = e.target.dataset.video_download - audio_title.innerText = e.target.dataset.music_title - audio.src = e.target.dataset.music_url +// -- HELPERS -- // +const getHash = () => window.location.hash.substring(1) + +const getVideoDataById = (id) => { + const el = document.getElementById(id) + if (el) { + return el.dataset + } + return false +} + +const isModalActive = () => modal.classList.contains('is-active') + +const toggleButton = (id, force) => document.getElementById(id) ? document.getElementById(id).toggleAttribute('disabled', force) : alert('That button does not exist') + +// -- MODAL -- // +const swapData = ({ video_url, video_width, video_height, desc, video_download, music_title, music_url }) => { + video.src = video_url + video.width = video_width + video.height = video_height + item_title.innerText = desc + download_button.href = video_download + audio_title.innerText = music_title + audio.src = music_url +} + +const showModal = (id) => { + const dataset = getVideoDataById(id) + if (dataset) { + swapData(dataset) modal.classList.toggle('is-active') video.play() + } } const hideModel = () => { - video.pause() - audio.pause() - video.currentTime = 0 - modal.classList.toggle('is-active') - video.width = '' - video.height = '' + video.pause() + audio.pause() + video.currentTime = 0 + modal.classList.toggle('is-active') + toggleButton('back-button', false) + toggleButton('next-button', false) + history.pushState('', document.title, window.location.pathname + window.location.search) +} + +const getPrevOrNext = (forward) => { + const hash = getHash() + if (hash) { + const el = document.getElementById(hash) + if (el) { + if (forward) { + return el.parentElement.nextElementSibling ? el.parentElement.nextElementSibling.children[0] : null + } + return el.parentElement.previousElementSibling ? el.parentElement.previousElementSibling.children[0] : null + } + } + return null +} + +const moveVideo = (forward) => { + // Re-enable buttons + toggleButton('back-button', false) + toggleButton('next-button', false) + const new_el = getPrevOrNext(forward) + if (new_el) { + window.location.hash = new_el.id + } else { + // Max reached, disable buttons depending on direction + if (forward) { + toggleButton('next-button', true) + } else { + toggleButton('back-button', true) + } + } } // EVENTS // - -// Click to show modal -const figures = document.getElementsByClassName("clickable-img") -for (let i = 0; i < figures.length; i++) { - const figure = figures[i] - figure.addEventListener('click', showModal, true) +const hashChange = () => { + if (window.location.hash) { + const hash = getHash() + if (hash) { + // Check first if the modal is already active + if (isModalActive()) { + // If it is, get hash video id and swap data + const dataset = getVideoDataById(hash) + if (dataset) { + swapData(dataset) + video.play() + } + } else { + showModal(hash) + } + } + } } -// Click to hide modal -document.getElementById('modal-background').addEventListener('click', hideModel, true) -document.getElementById('modal-close').addEventListener('click', hideModel, true) +document.getElementById('modal-background').addEventListener('click', hideModel, false) +document.getElementById('modal-close').addEventListener('click', hideModel, false) +document.getElementById('back-button').addEventListener('click', () => moveVideo(false)) +document.getElementById('next-button').addEventListener('click', () => moveVideo(true)) +window.addEventListener('hashchange', hashChange, false) + +hashChange() diff --git a/styles/user.css b/styles/user.css index 8dc4f84..1616e19 100644 --- a/styles/user.css +++ b/styles/user.css @@ -1,9 +1,3 @@ -/* -.modal-card-body { - background-color: transparent; -} -*/ - #video { height: 100%; overflow: hidden; diff --git a/views/home.html b/views/home.html index 73d2327..3e73f08 100644 --- a/views/home.html +++ b/views/home.html @@ -15,21 +15,26 @@

Welcome to TikTok Viewer!

Alternative TikTok Frontend

-
-
- +
+
+
+ +
+
+ +
-
- -
-
+
diff --git a/views/user.blade.php b/views/user.blade.php index 5f00c9a..6a59946 100644 --- a/views/user.blade.php +++ b/views/user.blade.php @@ -21,25 +21,27 @@
@foreach ($user->items as $item)
-
- -
+ + +
@endforeach
- Last page + @isset ($_GET['cursor']) + First + @endisset + Back @if ($user->hasMore) - Next page + Next @else - Next page + Next @endif
@@ -47,17 +49,21 @@