Patching system, video by id
This commit is contained in:
parent
38fa75402b
commit
c6b0f1e812
|
@ -6,6 +6,7 @@ Use Tiktok using an alternative frontend, inspired by Nitter.
|
|||
* See user's feed
|
||||
* See trending
|
||||
* See tags
|
||||
* See video by id
|
||||
* Create a following list, which you can later use to see all the feeds from those users
|
||||
|
||||
## Installation
|
||||
|
@ -44,11 +45,14 @@ location /tiktok-viewer/.env {
|
|||
```
|
||||
|
||||
## 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). **This is automatically patched after running composer install**
|
||||
* Fetching a user fails, 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).
|
||||
* Fetching a video by id or by url fails
|
||||
**These issues are automatically patched after running composer install**
|
||||
|
||||
## TODO
|
||||
* Allow searching for just one video using the ID
|
||||
* Add a NoJS version / Make the whole program without required JS
|
||||
* Better error handling
|
||||
* Make video on /video fit screen and don't overflow
|
||||
|
||||
## Credits
|
||||
* [TikTok-API-PHP](https://github.com/ssovit/TikTok-API-PHP)
|
||||
|
|
|
@ -1,24 +1,33 @@
|
|||
{
|
||||
"name": "pablouser1/tiktok-viewer",
|
||||
"description": "An alternative frontend for TikTok",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"ext-curl": "*",
|
||||
"ssovit/tiktok-api": "^2.0",
|
||||
"steampixel/simple-php-router": "^0.7.0",
|
||||
"latte/latte": "^2.10",
|
||||
"vlucas/phpdotenv": "^5.4"
|
||||
"vlucas/phpdotenv": "^5.4",
|
||||
"cweagans/composer-patches": "^1.7"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Helpers\\": "helpers/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-install-cmd": [
|
||||
"php fix_api.php"
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"cweagans/composer-patches": true
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"patches": {
|
||||
"ssovit/tiktok-api": [
|
||||
"patches/0001-Fixed-getUser.patch",
|
||||
"patches/0002-Added-support-for-username-as-well-as-user-id.patch",
|
||||
"patches/0003-Fixed-getVideoByUrl.patch"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
107
composer.lock
generated
107
composer.lock
generated
|
@ -4,8 +4,56 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "e064040cff1f97fef9172828540a1aac",
|
||||
"content-hash": "f82588da7787761ecda16112b8c1d1b1",
|
||||
"packages": [
|
||||
{
|
||||
"name": "cweagans/composer-patches",
|
||||
"version": "1.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cweagans/composer-patches.git",
|
||||
"reference": "9888dcc74993c030b75f3dd548bb5e20cdbd740c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cweagans/composer-patches/zipball/9888dcc74993c030b75f3dd548bb5e20cdbd740c",
|
||||
"reference": "9888dcc74993c030b75f3dd548bb5e20cdbd740c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-plugin-api": "^1.0 || ^2.0",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "~1.0 || ~2.0",
|
||||
"phpunit/phpunit": "~4.6"
|
||||
},
|
||||
"type": "composer-plugin",
|
||||
"extra": {
|
||||
"class": "cweagans\\Composer\\Patches"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"cweagans\\Composer\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cameron Eagans",
|
||||
"email": "me@cweagans.net"
|
||||
}
|
||||
],
|
||||
"description": "Provides a way to patch Composer packages.",
|
||||
"support": {
|
||||
"issues": "https://github.com/cweagans/composer-patches/issues",
|
||||
"source": "https://github.com/cweagans/composer-patches/tree/1.7.1"
|
||||
},
|
||||
"time": "2021-06-08T15:12:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "graham-campbell/result-type",
|
||||
"version": "v1.0.4",
|
||||
|
@ -70,16 +118,16 @@
|
|||
},
|
||||
{
|
||||
"name": "latte/latte",
|
||||
"version": "v2.10.7",
|
||||
"version": "v2.10.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nette/latte.git",
|
||||
"reference": "a69d0b9598652438b5754ae5c1abc217d5003d98"
|
||||
"reference": "596b28bf098ebb852732d60b00538139a009c4db"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nette/latte/zipball/a69d0b9598652438b5754ae5c1abc217d5003d98",
|
||||
"reference": "a69d0b9598652438b5754ae5c1abc217d5003d98",
|
||||
"url": "https://api.github.com/repos/nette/latte/zipball/596b28bf098ebb852732d60b00538139a009c4db",
|
||||
"reference": "596b28bf098ebb852732d60b00538139a009c4db",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -148,9 +196,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nette/latte/issues",
|
||||
"source": "https://github.com/nette/latte/tree/v2.10.7"
|
||||
"source": "https://github.com/nette/latte/tree/v2.10.8"
|
||||
},
|
||||
"time": "2021-12-21T11:22:49+00:00"
|
||||
"time": "2022-01-04T14:13:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoption/phpoption",
|
||||
|
@ -314,21 +362,24 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.23.0",
|
||||
"version": "v1.24.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
|
||||
"reference": "30885182c981ab175d4d034db0f6f469898070ab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
|
||||
"reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
|
||||
"reference": "30885182c981ab175d4d034db0f6f469898070ab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
|
@ -373,7 +424,7 @@
|
|||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0"
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -389,25 +440,28 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-19T12:13:01+00:00"
|
||||
"time": "2021-10-20T20:35:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.23.1",
|
||||
"version": "v1.24.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6"
|
||||
"reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6",
|
||||
"reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825",
|
||||
"reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
|
@ -453,7 +507,7 @@
|
|||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1"
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -469,20 +523,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-05-27T12:26:48+00:00"
|
||||
"time": "2021-11-30T18:21:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.23.1",
|
||||
"version": "v1.24.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be"
|
||||
"reference": "57b712b08eddb97c762a8caa32c84e037892d2e9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be",
|
||||
"reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9",
|
||||
"reference": "57b712b08eddb97c762a8caa32c84e037892d2e9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -536,7 +590,7 @@
|
|||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1"
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -552,7 +606,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-07-28T13:41:28+00:00"
|
||||
"time": "2021-09-13T13:58:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "vlucas/phpdotenv",
|
||||
|
@ -642,9 +696,8 @@
|
|||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": "^7.3|^8.0",
|
||||
"ext-curl": "*"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.0.0"
|
||||
"plugin-api-version": "2.2.0"
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
if (!file_exists(__DIR__ . '/.new_api')) {
|
||||
$new_api = file_get_contents('https://raw.githubusercontent.com/attend-dunce/TikTok-API-PHP/master/lib/TikTok/Api.php');
|
||||
file_put_contents(__DIR__ . '/vendor/ssovit/tiktok-api/lib/TikTok/Api.php', $new_api);
|
||||
file_put_contents(__DIR__ . '/.new_api', 'DO NOT DELETE! This file proves that you have patched the API');
|
||||
echo('Patched API!');
|
||||
}
|
40
patches/0001-Fixed-getUser.patch
Normal file
40
patches/0001-Fixed-getUser.patch
Normal file
|
@ -0,0 +1,40 @@
|
|||
From 7c52f9291fbd15d912fa78d0301939e3aa9deec4 Mon Sep 17 00:00:00 2001
|
||||
From: attend-dunce <96889312+attend-dunce@users.noreply.github.com>
|
||||
Date: Thu, 30 Dec 2021 21:35:14 +0100
|
||||
Subject: [PATCH 1/3] Fixed `getUser`
|
||||
|
||||
---
|
||||
lib/TikTok/Api.php | 16 +++++++---------
|
||||
1 file changed, 7 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/lib/TikTok/Api.php b/lib/TikTok/Api.php
|
||||
index e605eef..4a35f61 100644
|
||||
--- a/lib/TikTok/Api.php
|
||||
+++ b/lib/TikTok/Api.php
|
||||
@@ -385,16 +385,14 @@ if (!\class_exists('\Sovit\TikTok\Api')) {
|
||||
}
|
||||
}
|
||||
$username = urlencode($username);
|
||||
- $result = $this->remote_call("https://www.tiktok.com/@{$username}?lang=en", false);
|
||||
- if (preg_match('/<script id="__NEXT_DATA__"([^>]+)>([^<]+)<\/script>/', $result, $matches)) {
|
||||
- $result = json_decode($matches[2], false);
|
||||
- if (isset($result->props->pageProps->userInfo)) {
|
||||
- $result = $result->props->pageProps->userInfo;
|
||||
- if ($this->cacheEnabled) {
|
||||
- $this->cacheEngine->set($cacheKey, $result, $this->_config['cache-timeout']);
|
||||
- }
|
||||
- return $result;
|
||||
+ $result = $this->remote_call("https://www.tiktok.com/api/user/detail/?userId={$username}", false);
|
||||
+ $result = json_decode($result, false);
|
||||
+ if (isset($result->userInfo)) {
|
||||
+ $result = $result->userInfo;
|
||||
+ if ($this->cacheEnabled) {
|
||||
+ $this->cacheEngine->set($cacheKey, $result, $this->_config['cache-timeout']);
|
||||
}
|
||||
+ return $result;
|
||||
}
|
||||
return $this->failure();
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
From c948bda5d6f30929b448fe78a0920739d5792d4b Mon Sep 17 00:00:00 2001
|
||||
From: attend-dunce <96889312+attend-dunce@users.noreply.github.com>
|
||||
Date: Fri, 31 Dec 2021 00:55:23 +0100
|
||||
Subject: [PATCH 2/3] Added support for username as well as user id
|
||||
|
||||
---
|
||||
lib/TikTok/Api.php | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/TikTok/Api.php b/lib/TikTok/Api.php
|
||||
index 4a35f61..8fd42ae 100644
|
||||
--- a/lib/TikTok/Api.php
|
||||
+++ b/lib/TikTok/Api.php
|
||||
@@ -385,7 +385,8 @@ if (!\class_exists('\Sovit\TikTok\Api')) {
|
||||
}
|
||||
}
|
||||
$username = urlencode($username);
|
||||
- $result = $this->remote_call("https://www.tiktok.com/api/user/detail/?userId={$username}", false);
|
||||
+ $param = is_numeric($username) ? "userId" : "uniqueId";
|
||||
+ $result = $this->remote_call("https://www.tiktok.com/api/user/detail/?{$param}={$username}", false);
|
||||
$result = json_decode($result, false);
|
||||
if (isset($result->userInfo)) {
|
||||
$result = $result->userInfo;
|
||||
--
|
||||
2.34.1
|
||||
|
50
patches/0003-Fixed-getVideoByUrl.patch
Normal file
50
patches/0003-Fixed-getVideoByUrl.patch
Normal file
|
@ -0,0 +1,50 @@
|
|||
From c23e8dbf0bd722799cf19182142d4b177f8fd933 Mon Sep 17 00:00:00 2001
|
||||
From: Pablo Ferreiro <pferreiromero@gmail.com>
|
||||
Date: Sat, 8 Jan 2022 15:47:21 +0100
|
||||
Subject: [PATCH 3/3] Fixed getVideoByUrl
|
||||
|
||||
---
|
||||
lib/TikTok/Api.php | 19 +++++++++++++------
|
||||
1 file changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/lib/TikTok/Api.php b/lib/TikTok/Api.php
|
||||
index 8fd42ae..f800555 100644
|
||||
--- a/lib/TikTok/Api.php
|
||||
+++ b/lib/TikTok/Api.php
|
||||
@@ -483,20 +483,27 @@ if (!\class_exists('\Sovit\TikTok\Api')) {
|
||||
throw new \Exception("Invalid VIDEO URL");
|
||||
}
|
||||
$result = $this->remote_call($url, false);
|
||||
- $result = Helper::string_between($result, '{"props":{"initialProps":{', "</script>");
|
||||
+ $result = Helper::string_between($result, "window['SIGI_STATE']=", ";window['SIGI_RETRY']=");
|
||||
if (!empty($result)) {
|
||||
- $jsonData = json_decode('{"props":{"initialProps":{' . $result);
|
||||
- if (isset($jsonData->props->pageProps->itemInfo->itemStruct)) {
|
||||
+ $jsonData = json_decode($result);
|
||||
+ if (isset($jsonData->ItemModule, $jsonData->ItemList, $jsonData->UserModule)) {
|
||||
+ $id = $jsonData->ItemList->video->keyword;
|
||||
+ $item = $jsonData->ItemModule->{$id};
|
||||
+ $username = $item->author;
|
||||
$result = (object) [
|
||||
'statusCode' => 0,
|
||||
'info' => (object) [
|
||||
'type' => 'video',
|
||||
- 'detail' => $url,
|
||||
+ 'detail' => (object) [
|
||||
+ "url" => $url,
|
||||
+ "user" => $jsonData->UserModule->users->{$username},
|
||||
+ "stats" => $item->stats
|
||||
+ ],
|
||||
],
|
||||
- "items" => [$jsonData->props->pageProps->itemInfo->itemStruct],
|
||||
+ "items" => [$item],
|
||||
"hasMore" => false,
|
||||
"minCursor" => '0',
|
||||
- "maxCursor" => ' 0',
|
||||
+ "maxCursor" => '0'
|
||||
];
|
||||
if ($this->cacheEnabled) {
|
||||
$this->cacheEngine->set($cacheKey, $result, $this->_config['cache-timeout']);
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -1,18 +1,19 @@
|
|||
<?php
|
||||
use Steampixel\Route;
|
||||
|
||||
const VALID_TIKTOK_DOMAINS = [
|
||||
"tiktokcdn.com", "tiktokcdn-us.com", "tiktok.com"
|
||||
];
|
||||
|
||||
/**
|
||||
* Check if an url has a valid domain
|
||||
* @param string $url URL you want to check
|
||||
* @return bool
|
||||
*/
|
||||
function isValidDomain(string $url): bool {
|
||||
$valid_domains = [
|
||||
"tiktokcdn.com", "tiktokcdn-us.com", "tiktok.com"
|
||||
];
|
||||
$host = parse_url($url, PHP_URL_HOST);
|
||||
$host_split = explode('.', $host);
|
||||
return count($host_split) === 3 && in_array($host_split[1] . '.' . $host_split[2], $valid_domains);
|
||||
return count($host_split) === 3 && in_array($host_split[1] . '.' . $host_split[2], VALID_TIKTOK_DOMAINS);
|
||||
}
|
||||
|
||||
Route::add('/stream', function () {
|
||||
|
|
|
@ -10,6 +10,11 @@ Route::add('/', function () {
|
|||
$latte->render(Misc::getView('home'));
|
||||
});
|
||||
|
||||
Route::add('/about', function () {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('about'));
|
||||
});
|
||||
|
||||
Route::add("/trending", function () {
|
||||
$cursor = 0;
|
||||
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
|
||||
|
@ -44,6 +49,17 @@ Route::add("/@([^/]+)", function (string $username) {
|
|||
}
|
||||
});
|
||||
|
||||
Route::add('/video/(\d+)', function (string $video_id) {
|
||||
$latte = Misc::latte();
|
||||
$api = Misc::api();
|
||||
$item = $api->getVideoByID($video_id);
|
||||
if ($item) {
|
||||
$latte->render(Misc::getView('video'), ['item' => $item]);
|
||||
} else {
|
||||
return 'ERROR!';
|
||||
}
|
||||
});
|
||||
|
||||
Route::add('/tag/(\w+)', function (string $name) {
|
||||
$cursor = 0;
|
||||
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
|
||||
|
|
|
@ -21,10 +21,8 @@ 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 }) => {
|
||||
const swapData = ({ video_url, 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
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
const goToUser = (e) => {
|
||||
const goToUser = e => {
|
||||
e.preventDefault()
|
||||
const formData = new FormData(e.target)
|
||||
const username = formData.get('username')
|
||||
window.location.href = `./@${username}`
|
||||
}
|
||||
|
||||
const goToTag = (e) => {
|
||||
const goToTag = e => {
|
||||
e.preventDefault()
|
||||
const formData = new FormData(e.target)
|
||||
const tag = formData.get('tag')
|
||||
window.location.href = `./tag/${tag}`
|
||||
}
|
||||
|
||||
const goToVideo = e => {
|
||||
e.preventDefault()
|
||||
const formData = new FormData(e.target)
|
||||
const video_id = formData.get('video_id')
|
||||
window.location.href = `./video/${video_id}`
|
||||
}
|
||||
|
||||
document.getElementById('username_form').addEventListener('submit', goToUser, false)
|
||||
document.getElementById('tag_form').addEventListener('submit', goToTag, false)
|
||||
document.getElementById('video_form').addEventListener('submit', goToVideo, false)
|
||||
|
|
2
styles/bulma.min.css
vendored
2
styles/bulma.min.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
styles/scss/bulma.scss
vendored
3
styles/scss/bulma.scss
vendored
|
@ -10,6 +10,7 @@
|
|||
|
||||
// Elements
|
||||
@import "./node_modules/bulma/sass/elements/button.sass";
|
||||
@import "./node_modules/bulma/sass/elements/box.sass";
|
||||
@import "./node_modules/bulma/sass/elements/container.sass";
|
||||
@import "./node_modules/bulma/sass/elements/other.sass";
|
||||
@import "./node_modules/bulma/sass/elements/tag.sass";
|
||||
|
@ -17,7 +18,7 @@
|
|||
|
||||
// Form
|
||||
@import "./node_modules/bulma/sass/form/shared.sass";
|
||||
@import "./node_modules/bulma/sass/form/checkbox_radio.sass";
|
||||
@import "./node_modules/bulma/sass/form/checkbox-radio.sass";
|
||||
@import "./node_modules/bulma/sass/form/tools.sass";
|
||||
|
||||
// Components
|
||||
|
|
|
@ -113,9 +113,9 @@ readdirp@~3.6.0:
|
|||
picomatch "^2.2.1"
|
||||
|
||||
sass@^1.46.0:
|
||||
version "1.46.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.46.0.tgz#923117049525236026a7ede69715580eb0fac751"
|
||||
integrity sha512-Z4BYTgioAOlMmo4LU3Ky2txR8KR0GRPLXxO38kklaYxgo7qMTgy+mpNN4eKsrXDTFlwS5vdruvazG4cihxHRVQ==
|
||||
version "1.47.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.47.0.tgz#c22dd0eed2e4a991430dae0b03c8e694bc41c2b4"
|
||||
integrity sha512-GtXwvwgD7/6MLUZPnlA5/8cdRgC9SzT5kAnnJMRmEZQFRE3J56Foswig4NyyyQGsnmNvg6EUM/FP0Pe9Y2zywQ==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
data-video_url="{path('stream?url=' . urlencode($item->video->playAddr))}"
|
||||
data-video_download="{path('stream?url=' . urlencode($item->video->playAddr) . '&download=1')}"
|
||||
data-desc="{$item->desc}"
|
||||
data-video_width="{$item->video->width}"
|
||||
data-video_height="{$item->video->height}"
|
||||
data-music_title="{$item->music->title}"
|
||||
data-music_url="{path('stream?url=' . urlencode($item->music->playUrl))}">
|
||||
<img loading="lazy" src="{path('stream?url=' . urlencode($item->video->originCover))}" />
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<a href="{path('')}" class="navbar-item">Home</a>
|
||||
<a href="{path('following')}" class="navbar-item">Following</a>
|
||||
<a href="{path('settings')}" class="navbar-item">Settings</a>
|
||||
<a href="{path('about')}" class="navbar-item">About</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
@ -23,6 +23,18 @@
|
|||
</div>
|
||||
</form>
|
||||
<hr />
|
||||
<p>Search video by id:</p>
|
||||
<form id="video_form">
|
||||
<div class="field has-addons has-addons-centered">
|
||||
<div class="control">
|
||||
<input name="video_id" class="input" type="text" placeholder="Type video ID" required />
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button is-success" type="submit">Go</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<hr />
|
||||
<p>Search tag:</p>
|
||||
<form id="tag_form">
|
||||
<div class="field has-addons has-addons-centered">
|
||||
|
|
35
views/video.latte
Normal file
35
views/video.latte
Normal file
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
{include 'components/head.latte', title: $item->info->detail->user->nickname}
|
||||
|
||||
<body>
|
||||
<section class="hero is-fullheight">
|
||||
<div class="hero-head">
|
||||
{include 'components/navbar.latte'}
|
||||
</div>
|
||||
<div class="hero-body">
|
||||
<div class="columns">
|
||||
<div class="column has-text-centered">
|
||||
<video autoplay controls src="{path('stream?url=' . urlencode($item->items[0]->video->playAddr))}"></video>
|
||||
</div>
|
||||
<div class="column is-one-quarter">
|
||||
<div class="box container">
|
||||
<p class="title">Video by <a href="{path('@'.$item->info->detail->user->uniqueId)}">{$item->info->detail->user->uniqueId}</a></p>
|
||||
<p class="subtitle">{$item->items[0]->desc}</p>
|
||||
<p>Played {number($item->info->detail->stats->playCount)} times</p>
|
||||
<p>Shared {number($item->info->detail->stats->shareCount)} times / {number($item->info->detail->stats->commentCount)} comments</p>
|
||||
<hr />
|
||||
<a href="{path('stream?url=' . urlencode($item->items[0]->video->playAddr) . '&download=1')}" class="button is-info">Download video</a>
|
||||
<p>{$item->items[0]->music->title}</p>
|
||||
<audio src="{path('stream?url=' . urlencode($item->items[0]->music->playUrl))}" controls preload="none"></audio>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-foot">
|
||||
{include 'components/footer.latte'}
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue