Removed home.js

Added Discover
This commit is contained in:
Pablo Ferreiro 2022-02-06 00:58:30 +01:00
parent df052dab36
commit 8816f4a1a1
No known key found for this signature in database
GPG key ID: 41FBCE65B779FA24
25 changed files with 213 additions and 145 deletions

View file

@ -7,6 +7,7 @@ Use Tiktok with an alternative frontend, inspired by Nitter.
* See trending * See trending
* See tags * See tags
* See video by id * See video by id
* Discovery
* Create a following list, which you can later use to see all the feeds from those users * Create a following list, which you can later use to see all the feeds from those users
* RSS Feed for user, trending and tag (just add /rss to the url) * RSS Feed for user, trending and tag (just add /rss to the url)
@ -56,6 +57,7 @@ location /proxitok/.env {
* Add a NoJS version / Make the whole program without required JS * Add a NoJS version / Make the whole program without required JS
* Better error handling * Better error handling
* Make video on /video fit screen and don't overflow * Make video on /video fit screen and don't overflow
* Allow custom Region/Language
## Credits ## Credits
* [TikTok-API-PHP](https://github.com/ssovit/TikTok-API-PHP) (Currently using my personal fork) * [TikTok-API-PHP](https://github.com/ssovit/TikTok-API-PHP) (Currently using my personal fork)

View file

@ -0,0 +1,19 @@
<?php
namespace App\Controllers;
use App\Helpers\ErrorHandler;
use App\Helpers\Misc;
use App\Models\FeedTemplate;
class DiscoverController {
static public function get() {
$api = Misc::api();
$feed = $api->getDiscover();
if ($feed->meta->success) {
$latte = Misc::latte();
$latte->render(Misc::getView('discover'), new FeedTemplate('Discover', $feed));
} else {
ErrorHandler::show($feed->meta);
}
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace App\Controllers;
use App\Helpers\Misc;
/**
* Used to be compatible with HTML forms
*/
class RedirectController {
static public function redirect() {
$endpoint = '';
if (isset($_GET['user'])) {
$endpoint = '/@' . $_GET['user'];
} else if (isset($_GET['tag'])) {
$endpoint = '/tag/' . $_GET['tag'];
} else if (isset($_GET['music'])) {
$endpoint = '/music/' . $_GET['music'];
} else if (isset($_GET['video'])) {
$endpoint = '/video/' . $_GET['video'];
}
$url = Misc::url($endpoint);
header("Location: {$url}");
}
}

View file

@ -18,8 +18,7 @@ class SettingsController {
Cookies::set($proxy_element, $_POST[$proxy_element]); Cookies::set($proxy_element, $_POST[$proxy_element]);
} }
} }
http_response_code(302); $url = Misc::url('/settings');
$url = Misc::env('APP_URL', '');
header("Location: {$url}"); header("Location: {$url}");
} }
@ -49,6 +48,7 @@ class SettingsController {
// Build string // Build string
$following_string = implode(',', $following); $following_string = implode(',', $following);
Cookies::set('following', $following_string); Cookies::set('following', $following_string);
header('Location: ../settings'); $url = Misc::url('/settings');
header("Location: {$url}");
} }
} }

View file

@ -1,10 +1,12 @@
<?php <?php
namespace App\Helpers; namespace App\Helpers;
use App\Models\ErrorTemplate;
class ErrorHandler { class ErrorHandler {
static public function show(object $meta) { static public function show(object $meta) {
http_response_code($meta->http_code); http_response_code($meta->http_code);
$latte = Misc::latte(); $latte = Misc::latte();
$latte->render(Misc::getView('error'), ['error' => $meta]); $latte->render(Misc::getView('error'), new ErrorTemplate($meta));
} }
} }

View file

@ -1,7 +1,6 @@
<?php <?php
namespace App\Helpers; namespace App\Helpers;
use Exception;
use App\Cache\JSONCache; use App\Cache\JSONCache;
use App\Cache\RedisCache; use App\Cache\RedisCache;
@ -10,11 +9,11 @@ class Misc {
return isset($_GET['cursor']) && is_numeric($_GET['cursor']) ? (int) $_GET['cursor'] : 0; return isset($_GET['cursor']) && is_numeric($_GET['cursor']) ? (int) $_GET['cursor'] : 0;
} }
static public function getURL(): string { static public function url(string $endpoint = '') {
return self::env('APP_URL', ''); return self::env('APP_URL', '') . $endpoint;
} }
static public function env(string $key, mixed $default_value): string { static public function env(string $key, string $default_value): string {
return isset($_ENV[$key]) && !empty($_ENV[$key]) ? $_ENV[$key] : $default_value; return isset($_ENV[$key]) && !empty($_ENV[$key]) ? $_ENV[$key] : $default_value;
} }
@ -45,7 +44,7 @@ class Misc {
break; break;
case 'redis': case 'redis':
if (!isset($_ENV['REDIS_URL'])) { if (!isset($_ENV['REDIS_URL'])) {
throw new Exception('You need to set REDIS_URL to use Redis Cache!'); throw new \Exception('You need to set REDIS_URL to use Redis Cache!');
} }
$url = parse_url($_ENV['REDIS_URL']); $url = parse_url($_ENV['REDIS_URL']);
@ -64,24 +63,17 @@ class Misc {
* Setup of Latte template engine * Setup of Latte template engine
*/ */
static public function latte(): \Latte\Engine { static public function latte(): \Latte\Engine {
// Workaround to avoid weird path issues
$url = self::getURL();
$latte = new \Latte\Engine; $latte = new \Latte\Engine;
$cache_path = self::env('LATTE_CACHE', __DIR__ . '/../../cache/latte'); $cache_path = self::env('LATTE_CACHE', __DIR__ . '/../../cache/latte');
$latte->setTempDirectory($cache_path); $latte->setTempDirectory($cache_path);
// -- CUSTOM FUNCTIONS -- // // -- CUSTOM FUNCTIONS -- //
// Import assets // Get URL with optional endpoint
$latte->addFunction('assets', function (string $name, string $type) use ($url) { $latte->addFunction('path', function (string $endpoint = ''): string {
$path = "{$url}/{$type}/{$name}"; return self::url($endpoint);
return $path;
});
// Get base URL
$latte->addFunction('path', function (string $path = '') use ($url) {
return "{$url}/{$path}";
}); });
// Version being used // Version being used
$latte->addFunction('version', function () { $latte->addFunction('version', function (): string {
return \Composer\InstalledVersions::getVersion('pablouser1/proxitok'); return \Composer\InstalledVersions::getVersion('pablouser1/proxitok');
}); });
// https://stackoverflow.com/a/36365553 // https://stackoverflow.com/a/36365553
@ -98,10 +90,6 @@ class Misc {
} }
return $x; return $x;
}); });
$latte->addFunction('size', function (string $url) {
$download = new \Sovit\TikTok\Download();
return $download->file_size($url);
});
return $latte; return $latte;
} }
} }

View file

@ -0,0 +1,11 @@
<?php
namespace App\Models;
class ErrorTemplate extends BaseTemplate {
public object $error;
function __construct(object $error) {
parent::__construct('Error');
$this->error = $error;
}
}

View file

@ -0,0 +1,34 @@
<?php
namespace App\Models;
/**
* Exclusive for /
*/
class HomeTemplate extends BaseTemplate {
public array $forms = [
[
'title' => 'Search by user',
'input' => 'user',
'placeholder' => 'Type username'
],
[
'title' => 'Search by video ID',
'input' => 'video',
'placeholder' => 'Type video ID'
],
[
'title' => 'Search by tag',
'input' => 'tag',
'placeholder' => 'Type tag'
],
[
'title' => 'Search by music ID',
'input' => 'music',
'placeholder' => 'Type music'
]
];
function __construct() {
parent::__construct('Home');
}
}

View file

@ -1,16 +1,17 @@
<link rel="stylesheet" href="{assets('feed.css', 'styles')}"> <link rel="stylesheet" href="{path('/styles/feed.css')}">
<noscript>JavaScript is required for this section to work!</noscript>
<section class="section"> <section class="section">
<div class="columns is-multiline is-vcentered"> <div class="columns is-multiline is-vcentered">
{foreach $feed->items as $item} {foreach $feed->items as $item}
<div class="column is-one-quarter"> <div class="column is-one-quarter">
<a class="clickable-img" id="{$item->id}" href="#{$item->id}" <a class="clickable-img" id="{$item->id}" href="#{$item->id}"
data-video_url="{path('stream?url=' . urlencode($item->video->playAddr))}" data-video_url="{path('/stream?url=' . urlencode($item->video->playAddr))}"
data-video_download="{path('stream?url=' . urlencode($item->video->playAddr) . '&download=1')}" data-video_download="{path('/stream?url=' . urlencode($item->video->playAddr) . '&download=1')}"
data-desc="{$item->desc}" data-desc="{$item->desc}"
data-music_title="{$item->music->title}" data-music_title="{$item->music->title}"
data-music_url="{path('stream?url=' . urlencode($item->music->playUrl))}"> data-music_url="{path('/stream?url=' . urlencode($item->music->playUrl))}">
<img loading="lazy" src="{path('stream?url=' . urlencode($item->video->originCover))}" /> <img loading="lazy" src="{path('/stream?url=' . urlencode($item->video->originCover))}" />
<img class="hidden" loading="lazy" data-src="{path('stream?url=' . urlencode($item->video->dynamicCover))}" /> <img class="hidden" loading="lazy" data-src="{path('/stream?url=' . urlencode($item->video->dynamicCover))}" />
</a> </a>
</div> </div>
{/foreach} {/foreach}
@ -50,4 +51,4 @@
</footer> </footer>
</div> </div>
</div> </div>
<script src="{assets('feed.js', 'scripts')}"></script> <script src="{path('/scripts/feed.js')}"></script>

View file

@ -2,6 +2,6 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{assets('bulma.min.css', 'styles')}"> <link rel="stylesheet" href="{path('/styles/bulma.min.css')}">
<title>{$title} - ProxiTok</title> <title>{$title} - ProxiTok</title>
</head> </head>

View file

@ -9,11 +9,11 @@
<div id="navbar-menu" class="navbar-menu"> <div id="navbar-menu" class="navbar-menu">
<div class="navbar-start"> <div class="navbar-start">
<a href="{path('')}" class="navbar-item">Home</a> <a href="{path('/')}" class="navbar-item">Home</a>
<a href="{path('following')}" class="navbar-item">Following</a> <a href="{path('/following')}" class="navbar-item">Following</a>
<a href="{path('settings')}" class="navbar-item">Settings</a> <a href="{path('/settings')}" class="navbar-item">Settings</a>
<a href="{path('about')}" class="navbar-item">About</a> <a href="{path('/about')}" class="navbar-item">About</a>
</div> </div>
</div> </div>
</nav> </nav>
<script src="{assets('navbar.js', 'scripts')}"></script> <script src="{path('/scripts/navbar.js')}"></script>

View file

@ -1,5 +1,5 @@
{include '../following_tags.latte'} {include '../following_tags.latte'}
<form action="./settings/following" method="POST"> <form action="{path('/settings/following')}" method="POST">
<div class="field"> <div class="field">
<label class="label">Add / Remove user</label> <label class="label">Add / Remove user</label>
<div class="control"> <div class="control">

View file

@ -1,4 +1,4 @@
<form action="./settings/proxy" method="POST"> <form action="{path('/settings/proxy')}" method="POST">
{foreach $proxy_elements as $proxy_element} {foreach $proxy_elements as $proxy_element}
<div class="field"> <div class="field">
<label class="label">{$proxy_element}</label> <label class="label">{$proxy_element}</label>

View file

@ -1,8 +1,16 @@
{ {
"name": "pablouser1/proxitok", "name": "pablouser1/proxitok",
"description": "An alternative frontend for TikTok", "description": "An alternative frontend for TikTok",
"version": "1.3.2", "version": "1.4.0",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"type": "project",
"homepage": "https://github.com/pablouser1/ProxiTok",
"authors": [
{
"name": "Pablo Ferreiro",
"homepage": "https://github.com/pablouser1"
}
],
"repositories": [ "repositories": [
{ {
"type": "vcs", "type": "vcs",

16
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "bf98cf536ad098372082ff5899967548", "content-hash": "b5edb25fa0c50e39f24197b895670cc3",
"packages": [ "packages": [
{ {
"name": "bramus/router", "name": "bramus/router",
@ -381,12 +381,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/pablouser1/TikTok-API-PHP.git", "url": "https://github.com/pablouser1/TikTok-API-PHP.git",
"reference": "672e26d461804923324782c40c4e2d650fd01c6a" "reference": "26e3c089bc409a324136cd4465d5489210cb73c3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/pablouser1/TikTok-API-PHP/zipball/672e26d461804923324782c40c4e2d650fd01c6a", "url": "https://api.github.com/repos/pablouser1/TikTok-API-PHP/zipball/26e3c089bc409a324136cd4465d5489210cb73c3",
"reference": "672e26d461804923324782c40c4e2d650fd01c6a", "reference": "26e3c089bc409a324136cd4465d5489210cb73c3",
"shasum": "" "shasum": ""
}, },
"type": "library", "type": "library",
@ -425,7 +425,7 @@
"issues": "https://github.com/ssovit/TikTok-API-PHP/issues", "issues": "https://github.com/ssovit/TikTok-API-PHP/issues",
"email": "sovit.tamrakar@gmail.com" "email": "sovit.tamrakar@gmail.com"
}, },
"time": "2022-01-22T19:37:07+00:00" "time": "2022-02-05T23:47:32+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
@ -620,12 +620,12 @@
} }
}, },
"autoload": { "autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"files": [ "files": [
"bootstrap.php" "bootstrap.php"
], ],
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"classmap": [ "classmap": [
"Resources/stubs" "Resources/stubs"
] ]

View file

@ -1,10 +1,11 @@
<?php <?php
use App\Helpers\Misc; use App\Helpers\Misc;
use App\Models\BaseTemplate; use App\Models\BaseTemplate;
use App\Models\HomeTemplate;
$router->get('/', function () { $router->get('/', function () {
$latte = Misc::latte(); $latte = Misc::latte();
$latte->render(Misc::getView('home'), new BaseTemplate('Home')); $latte->render(Misc::getView('home'), new HomeTemplate);
}); });
$router->get('/about', function () { $router->get('/about', function () {
@ -13,6 +14,7 @@ $router->get('/about', function () {
}); });
$router->get('/stream', 'ProxyController@stream'); $router->get('/stream', 'ProxyController@stream');
$router->get('/redirect', 'RedirectController@redirect');
$router->mount('/trending', function () use ($router) { $router->mount('/trending', function () use ($router) {
$router->get('/', 'TrendingController@get'); $router->get('/', 'TrendingController@get');
@ -40,4 +42,5 @@ $router->mount('/settings', function () use ($router) {
$router->post('/following', 'SettingsController@following'); $router->post('/following', 'SettingsController@following');
}); });
$router->get('/discover', 'DiscoverController@get');
$router->get('/following', 'FollowingController@get'); $router->get('/following', 'FollowingController@get');

View file

@ -1,32 +0,0 @@
const goToUser = e => {
e.preventDefault()
const formData = new FormData(e.target)
const username = formData.get('username')
window.location.href = `./@${username}`
}
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}`
}
const goToMusic = e => {
e.preventDefault()
const formData = new FormData(e.target)
const video_id = formData.get('music_id')
window.location.href = `./music/${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)
document.getElementById('music_form').addEventListener('submit', goToMusic, false)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -24,8 +24,10 @@ $bulmaswatch-import-font: false;
@import "./node_modules/bulma/sass/form/tools.sass"; @import "./node_modules/bulma/sass/form/tools.sass";
// Components // Components
@import "./node_modules/bulma/sass/components/card.sass";
@import "./node_modules/bulma/sass/components/modal.sass"; @import "./node_modules/bulma/sass/components/modal.sass";
@import "./node_modules/bulma/sass/components/navbar.sass"; @import "./node_modules/bulma/sass/components/navbar.sass";
@import "./node_modules/bulma/sass/components/media.sass";
// Grids // Grids
@import "./node_modules/bulma/sass/grid/columns.sass"; @import "./node_modules/bulma/sass/grid/columns.sass";

View file

@ -113,9 +113,9 @@ readdirp@~3.6.0:
picomatch "^2.2.1" picomatch "^2.2.1"
sass@^1.46.0: sass@^1.46.0:
version "1.49.0" version "1.49.7"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.0.tgz#65ec1b1d9a6bc1bae8d2c9d4b392c13f5d32c078" resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.7.tgz#22a86a50552b9b11f71404dfad1b9ff44c6b0c49"
integrity sha512-TVwVdNDj6p6b4QymJtNtRS2YtLJ/CqZriGg0eIAbAKMlN8Xy6kbv33FsEZSF7FufFFM705SQviHjjThfaQ4VNw== integrity sha512-13dml55EMIR2rS4d/RDHHP0sXMY3+30e1TKsyXaSz3iLWVoDWEoboY8WzJd5JMnxrRHffKO3wq2mpJ0jxRJiEQ==
dependencies: dependencies:
chokidar ">=3.0.0 <4.0.0" chokidar ">=3.0.0 <4.0.0"
immutable "^4.0.0" immutable "^4.0.0"

43
views/discover.latte Normal file
View file

@ -0,0 +1,43 @@
{layout '../layouts/default.latte'}
{block header}
<p class="title">Discover</p>
{/block}
{block content}
{foreach $feed->items as $type => $items}
<p class="title">{$type|firstUpper}</p>
<div class="columns is-multiline is-vcentered">
{foreach $items as $item}
<div class="column is-one-quarter">
<a href="{path($item->cardItem->link)}">
<div class="card">
<div class="card-content">
<div class="media">
<!-- Show image if exists -->
{if !empty($item->cardItem->cover)}
<div class="media-left">
<figure class="image is-96x96">
<img width="96" height="96" src="{path('/stream?url=' . urlencode($item->cardItem->cover))}" />
</figure>
</div>
{/if}
<div class="media-content">
<p class="title">{$item->cardItem->title}</p>
<p class="subtitle">{$item->cardItem->subTitle}</p>
</div>
</div>
<div class="content">
<p>{$item->cardItem->description}</p>
</div>
</div>
</div>
</a>
</div>
{/foreach}
</div>
{if !$iterator->last}
<hr />
{/if}
{/foreach}
{/block}

View file

@ -5,9 +5,6 @@
{/block} {/block}
{block content} {block content}
<p class="title">Following:</p> <p>{include '../components/following_tags.latte'}</p>
{include '../components/following_tags.latte'}
<p>You can add/remove follows on settings</p>
<hr />
{include '../components/feed.latte'} {include '../components/feed.latte'}
{/block} {/block}

View file

@ -3,11 +3,13 @@
{block content} {block content}
<p class="title">Welcome to ProxiTok!</p> <p class="title">Welcome to ProxiTok!</p>
<p class="subtitle">An alternative open source frontend for TikTok</p> <p class="subtitle">An alternative open source frontend for TikTok</p>
<p>Search user:</p> <!-- Create forms from App\Models\HomeTemplate -->
<form id="username_form"> {foreach $forms as $form}
<p>{$form['title']}</p>
<form action="{path('/redirect')}">
<div class="field has-addons has-addons-centered"> <div class="field has-addons has-addons-centered">
<div class="control"> <div class="control">
<input name="username" class="input" type="text" placeholder="Type username" required /> <input name="{$form['input']}" class="input" type="text" placeholder="{$form['placeholder']}" required />
</div> </div>
<div class="control"> <div class="control">
<button class="button is-success" type="submit">Go</button> <button class="button is-success" type="submit">Go</button>
@ -15,46 +17,10 @@
</div> </div>
</form> </form>
<hr /> <hr />
<p>Search video by id:</p> {/foreach}
<form id="video_form"> <p>Discover</p>
<div class="field has-addons has-addons-centered"> <a class="button is-success" href="{path('/discover')}">Go</a>
<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 /> <hr />
<p>Search tag:</p> <p>Trending</p>
<form id="tag_form"> <a class="button is-success" href="{path('/trending')}">Go</a>
<div class="field has-addons has-addons-centered">
<div class="control">
<input name="tag" class="input" type="text" placeholder="Type tag" required />
</div>
<div class="control">
<button class="button is-success" type="submit">Go</button>
</div>
</div>
</form>
<hr />
<p>Search music videos by id:</p>
<form id="music_form">
<div class="field has-addons has-addons-centered">
<div class="control">
<input name="music_id" class="input" type="text" placeholder="Type music id" required />
</div>
<div class="control">
<button class="button is-success" type="submit">Go</button>
</div>
</div>
</form>
<hr />
<p>Trending:</p>
<a class="button is-success" href="./trending">Go</a>
{/block}
{block extra}
<script src="{assets('home.js', 'scripts')}"></script>
{/block} {/block}

View file

@ -2,13 +2,13 @@
{block header} {block header}
<figure class="figure is-96x96"> <figure class="figure is-96x96">
<img src="{path('stream?url=' . urlencode($feed->info->detail->user->avatarThumb))}" /> <img src="{path('/stream?url=' . urlencode($feed->info->detail->user->avatarThumb))}" />
</figure> </figure>
<p class="title">{$feed->info->detail->user->uniqueId}'s profile</p> <p class="title">{$feed->info->detail->user->uniqueId}'s profile</p>
<p class="subtitle">{$feed->info->detail->user->signature}</p> <p class="subtitle">{$feed->info->detail->user->signature}</p>
<p>Following: {number($feed->info->detail->stats->followingCount)} / Followers: {number($feed->info->detail->stats->followerCount)}</p> <p>Following: {number($feed->info->detail->stats->followingCount)} / Followers: {number($feed->info->detail->stats->followerCount)}</p>
<p>Hearts: {number($feed->info->detail->stats->heartCount)} / Videos: {$feed->info->detail->stats->videoCount}</p> <p>Hearts: {number($feed->info->detail->stats->heartCount)} / Videos: {$feed->info->detail->stats->videoCount}</p>
<a href="{path('@' . $feed->info->detail->user->uniqueId . '/rss')}">RSS</a> <a href="{path('/@' . $feed->info->detail->user->uniqueId . '/rss')}">RSS</a>
{/block} {/block}
{block content} {block content}