Code cleanup, following and gif support

This commit is contained in:
Pablo Ferreiro 2022-01-06 00:11:00 +01:00
parent 493f56a052
commit 30954f3d3a
No known key found for this signature in database
GPG key ID: 41FBCE65B779FA24
21 changed files with 318 additions and 123 deletions

View file

@ -41,7 +41,6 @@ location /tiktok-viewer/.env {
## TODO ## TODO
* Allow searching for just one video using the ID * Allow searching for just one video using the ID
* Code cleanup
## Credits ## Credits
* [TikTok-API-PHP](https://github.com/ssovit/TikTok-API-PHP) * [TikTok-API-PHP](https://github.com/ssovit/TikTok-API-PHP)

View file

@ -11,6 +11,11 @@
"latte/latte": "^2.10", "latte/latte": "^2.10",
"vlucas/phpdotenv": "^5.4" "vlucas/phpdotenv": "^5.4"
}, },
"autoload": {
"psr-4": {
"Helpers\\": "helpers/"
}
},
"scripts": { "scripts": {
"post-install-cmd": [ "post-install-cmd": [
"php fix_api.php" "php fix_api.php"

54
composer.lock generated
View file

@ -70,16 +70,16 @@
}, },
{ {
"name": "latte/latte", "name": "latte/latte",
"version": "v2.10.7", "version": "v2.10.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nette/latte.git", "url": "https://github.com/nette/latte.git",
"reference": "a69d0b9598652438b5754ae5c1abc217d5003d98" "reference": "596b28bf098ebb852732d60b00538139a009c4db"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nette/latte/zipball/a69d0b9598652438b5754ae5c1abc217d5003d98", "url": "https://api.github.com/repos/nette/latte/zipball/596b28bf098ebb852732d60b00538139a009c4db",
"reference": "a69d0b9598652438b5754ae5c1abc217d5003d98", "reference": "596b28bf098ebb852732d60b00538139a009c4db",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -148,9 +148,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/nette/latte/issues", "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", "name": "phpoption/phpoption",
@ -314,21 +314,24 @@
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
"version": "v1.23.0", "version": "v1.24.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git", "url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" "reference": "30885182c981ab175d4d034db0f6f469898070ab"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
"reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", "reference": "30885182c981ab175d4d034db0f6f469898070ab",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.1" "php": ">=7.1"
}, },
"provide": {
"ext-ctype": "*"
},
"suggest": { "suggest": {
"ext-ctype": "For best performance" "ext-ctype": "For best performance"
}, },
@ -373,7 +376,7 @@
"portable" "portable"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0"
}, },
"funding": [ "funding": [
{ {
@ -389,25 +392,28 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-02-19T12:13:01+00:00" "time": "2021-10-20T20:35:02+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.23.1", "version": "v1.24.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825",
"reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.1" "php": ">=7.1"
}, },
"provide": {
"ext-mbstring": "*"
},
"suggest": { "suggest": {
"ext-mbstring": "For best performance" "ext-mbstring": "For best performance"
}, },
@ -453,7 +459,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0"
}, },
"funding": [ "funding": [
{ {
@ -469,20 +475,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-05-27T12:26:48+00:00" "time": "2021-11-30T18:21:41+00:00"
}, },
{ {
"name": "symfony/polyfill-php80", "name": "symfony/polyfill-php80",
"version": "v1.23.1", "version": "v1.24.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php80.git", "url": "https://github.com/symfony/polyfill-php80.git",
"reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9",
"reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -536,7 +542,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0"
}, },
"funding": [ "funding": [
{ {
@ -552,7 +558,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-07-28T13:41:28+00:00" "time": "2021-09-13T13:58:33+00:00"
}, },
{ {
"name": "vlucas/phpdotenv", "name": "vlucas/phpdotenv",

12
helpers/Following.php Normal file
View file

@ -0,0 +1,12 @@
<?php
namespace Helpers;
class Following {
static public function get (): array {
$following_string = Settings::get('following');
if ($following_string) {
return explode(',', $following_string);
}
return [];
}
};

54
helpers/Misc.php Normal file
View file

@ -0,0 +1,54 @@
<?php
namespace Helpers;
use Helpers\Settings;
class Misc {
static public function getSubDir(): string {
return isset($_ENV['APP_SUBDIR']) && !empty($_ENV['APP_SUBDIR']) ? $_ENV['APP_SUBDIR'] : '';
}
static public function getView(string $template): string {
return __DIR__ . "/../views/{$template}.latte";
}
static public function api(): \Sovit\TikTok\Api {
$options = [];
// Proxy config
if (in_array(Settings::$proxy, $_COOKIE)) {
foreach (Settings::$proxy as $proxy_element) {
$options[$proxy_element] = $_COOKIE[$proxy_element];
}
}
$api = new \Sovit\TikTok\Api($options);
return $api;
}
static public function latte(): \Latte\Engine {
$subdir = Misc::getSubDir();
$latte = new \Latte\Engine;
$latte->setTempDirectory(__DIR__ . '/../cache/views');
$latte->addFunction('assets', function (string $name, string $type) use ($subdir) {
$path = "{$subdir}/{$type}/{$name}";
return $path;
});
$latte->addFunction('path', function (string $name) use ($subdir) {
$path = "{$subdir}/{$name}";
return $path;
});
// https://stackoverflow.com/a/36365553
$latte->addFunction('number', function (int $x) {
if($x > 1000) {
$x_number_format = number_format($x);
$x_array = explode(',', $x_number_format);
$x_parts = array('K', 'M', 'B', 'T');
$x_count_parts = count($x_array) - 1;
$x_display = $x;
$x_display = $x_array[0] . ((int) $x_array[1][0] !== 0 ? '.' . $x_array[1][0] : '');
$x_display .= $x_parts[$x_count_parts - 1];
return $x_display;
}
return $x;
});
return $latte;
}
}

21
helpers/Settings.php Normal file
View file

@ -0,0 +1,21 @@
<?php
namespace Helpers;
class Settings {
static public $proxy = ['proxy-host', 'proxy-port', 'proxy-username', 'proxy-password'];
static public function get(string $name): string {
if (isset($_COOKIE[$name]) && !empty($_COOKIE[$name])) {
return $_COOKIE[$name];
}
return '';
}
static public function exists(string $name): bool {
return isset($_COOKIE[$name]);
}
static public function set(string $name, string $value) {
setcookie($name, $value, time()+60*60*24*30, '', '', true, true);
}
};

View file

@ -1,2 +0,0 @@
<?php
$proxy_elements = ['proxy-host', 'proxy-port', 'proxy-username', 'proxy-password'];

View file

@ -1,16 +1,12 @@
<?php <?php
require __DIR__ . "/vendor/autoload.php"; require __DIR__ . "/vendor/autoload.php";
use Steampixel\Route; use Steampixel\Route;
use Helpers\Misc;
// LOAD DOTENV // LOAD DOTENV
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__); $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->safeLoad(); $dotenv->safeLoad();
// -- HELPERS -- //
function getSubdir(): string {
return isset($_ENV['APP_SUBDIR']) && !empty($_ENV['APP_SUBDIR']) ? $_ENV['APP_SUBDIR'] : '';
}
require __DIR__ . '/routes/index.php'; require __DIR__ . '/routes/index.php';
Route::run(getSubdir()); Route::run(Misc::getSubDir());

32
routes/following.php Normal file
View file

@ -0,0 +1,32 @@
<?php
use Helpers\Following;
use Helpers\Misc;
use Steampixel\Route;
// Showing
Route::add('/following', function () {
$allowed_items_total = isset($_GET['max']) && is_numeric($_GET['max']) && $_GET['max'] <= 100 ? $_GET['max'] : 20;
$following = Following::get();
$items = [];
if (count($following) !== 0) {
$api = Misc::api();
$max_items_per_user = $allowed_items_total / count($following);
foreach ($following as $user) {
$user_feed = $api->getUserFeed($user);
if ($user_feed) {
$max = count($user_feed->items) > $max_items_per_user ? $max_items_per_user : count($user_feed->items);
for ($i = 0; $i < $max; $i++) {
$item = $user_feed->items[$i];
array_push($items, $item);
}
}
}
}
$feed = (object) [
'items' => $items,
'hasMore' => false
];
$latte = Misc::latte();
$latte->render(Misc::getView('following'), ['following' => $following, 'feed' => $feed]);
});

View file

@ -1,104 +1,59 @@
<?php <?php
require __DIR__ . '/assets.php'; require __DIR__ . '/assets.php';
require __DIR__ . '/settings.php'; require __DIR__ . '/settings.php';
require __DIR__ . "/../helpers/settings_elements.php"; require __DIR__ . '/following.php';
use Steampixel\Route; use Steampixel\Route;
use Helpers\Misc;
// -- ROUTING HELPERS -- //
function getApi(array $proxy_elements): \Sovit\TikTok\Api {
$options = [];
// Proxy config
if (in_array($proxy_elements, $_COOKIE)) {
foreach ($proxy_elements as $proxy_element) {
$options[$proxy_element] = $_COOKIE[$proxy_element];
}
}
$api = new \Sovit\TikTok\Api($options);
return $api;
}
function getLatte(): \Latte\Engine {
$subdir = getSubdir();
$latte = new Latte\Engine;
$latte->setTempDirectory(__DIR__ . '/../cache/views');
$latte->addFunction('assets', function (string $name, string $type) use ($subdir) {
$path = "{$subdir}/{$type}/{$name}";
return $path;
});
$latte->addFunction('path', function (string $name) use ($subdir) {
$path = "{$subdir}/{$name}";
return $path;
});
// https://stackoverflow.com/a/36365553
$latte->addFunction('number', function (int $x) {
if($x > 1000) {
$x_number_format = number_format($x);
$x_array = explode(',', $x_number_format);
$x_parts = array('K', 'M', 'B', 'T');
$x_count_parts = count($x_array) - 1;
$x_display = $x;
$x_display = $x_array[0] . ((int) $x_array[1][0] !== 0 ? '.' . $x_array[1][0] : '');
$x_display .= $x_parts[$x_count_parts - 1];
return $x_display;
}
return $x;
});
return $latte;
}
function getView(string $template): string {
return __DIR__ . "/../views/{$template}.latte";
}
Route::add('/', function () { Route::add('/', function () {
$latte = getLatte(); $latte = Misc::latte();
$latte->render(getView('home')); $latte->render(Misc::getView('home'));
}); });
Route::add("/trending", function () use ($proxy_elements) { Route::add("/trending", function () {
$cursor = 0; $cursor = 0;
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) { if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
$cursor = (int) $_GET['cursor']; $cursor = (int) $_GET['cursor'];
} }
$latte = getLatte(); $latte = Misc::latte();
$api = getApi($proxy_elements); $api = Misc::api();
$feed = $api->getTrendingFeed($cursor); $feed = $api->getTrendingFeed($cursor);
if ($feed) { if ($feed) {
$latte->render(getView('trending'), ['feed' => $feed]); $latte->render(Misc::getView('trending'), ['feed' => $feed]);
} else { } else {
return 'ERROR!'; return 'ERROR!';
} }
}); });
Route::add("/@([^/]+)", function (string $username) use ($proxy_elements) { Route::add("/@([^/]+)", function (string $username) {
$cursor = 0; $cursor = 0;
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) { if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
$cursor = (int) $_GET['cursor']; $cursor = (int) $_GET['cursor'];
} }
$latte = getLatte(); $latte = Misc::latte();
$api = getApi($proxy_elements); $api = Misc::api();
$feed = $api->getUserFeed($username, $cursor); $feed = $api->getUserFeed($username, $cursor);
if ($feed) { if ($feed) {
if ($feed->info->detail->user->privateAccount) { if ($feed->info->detail->user->privateAccount) {
http_response_code(400); http_response_code(400);
return 'Private account detected! Not supported'; return 'Private account detected! Not supported';
} }
$latte->render(getView('user'), ['feed' => $feed]); $latte->render(Misc::getView('user'), ['feed' => $feed]);
} else { } else {
return 'ERROR!'; return 'ERROR!';
} }
}); });
Route::add('/tag/(\w+)', function (string $name) use ($proxy_elements) { Route::add('/tag/(\w+)', function (string $name) {
$cursor = 0; $cursor = 0;
if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) { if (isset($_GET['cursor']) && is_numeric($_GET['cursor'])) {
$cursor = (int) $_GET['cursor']; $cursor = (int) $_GET['cursor'];
} }
$latte = getLatte(); $latte = Misc::latte();
$api = getApi($proxy_elements); $api = Misc::api();
$feed = $api->getChallengeFeed($name, $cursor); $feed = $api->getChallengeFeed($name, $cursor);
if ($feed) { if ($feed) {
$latte->render(getView('tag'), ['feed' => $feed]); $latte->render(Misc::getView('tag'), ['feed' => $feed]);
} else { } else {
return 'ERROR!'; return 'ERROR!';
} }

View file

@ -1,18 +1,43 @@
<?php <?php
require __DIR__ . "/../helpers/settings_elements.php";
use Helpers\Following;
use Helpers\Settings;
use Helpers\Misc;
use Steampixel\Route; use Steampixel\Route;
Route::add("/settings", function () use ($proxy_elements) { Route::add("/settings", function () {
$latte = getLatte(); $latte = Misc::latte();
$latte->render(getView('settings'), ["proxy_elements" => $proxy_elements]); $latte->render(Misc::getView('settings'), ["proxy_elements" => Settings::$proxy, "following" => Following::get()]);
}); });
Route::add("/settings", function () use ($proxy_elements) { Route::add("/settings/proxy", function () {
if (in_array($proxy_elements, $_POST)) { if (in_array(Settings::$proxy, $_POST)) {
foreach ($proxy_elements as $proxy_element) { foreach (Settings::$proxy as $proxy_element) {
setcookie($proxy_element, $_POST[$proxy_element], time()+60*60*24*30, '/', '', true, true); Settings::set($proxy_element, $_POST[$proxy_element]);
} }
} }
http_response_code(302); http_response_code(302);
header('Location: ./home'); header('Location: ./home');
}, 'POST'); }, 'POST');
Route::add("/settings/following", function () {
$following = Following::get();
if (isset($_POST['add'])) {
// Add following
array_push($following, $_POST['account']);
} elseif (isset($_POST['remove'])) {
$index = array_search($_POST['account'], $following);
if ($index !== false) {
unset($following[$index]);
}
} else {
return 'You need to send a mode!';
}
// Build string
$following_string = implode(',', $following);
Settings::set('following', $following_string);
header('Location: ../settings');
}, 'POST');

View file

@ -101,10 +101,32 @@ const hashChange = () => {
} }
} }
const swapImages = (e, mode) => {
if (mode === 'gif') {
const a = e.target
const img = a.children[0]
const gif = a.children[1]
img.classList.add('hidden')
gif.classList.remove('hidden')
} else if (mode === 'img') {
const gif = e.target
const img = e.target.parentElement.children[0]
img.classList.remove('hidden')
gif.classList.add('hidden')
}
}
document.getElementById('modal-background').addEventListener('click', hideModel, false) document.getElementById('modal-background').addEventListener('click', hideModel, false)
document.getElementById('modal-close').addEventListener('click', hideModel, false) document.getElementById('modal-close').addEventListener('click', hideModel, false)
document.getElementById('back-button').addEventListener('click', () => moveVideo(false)) document.getElementById('back-button').addEventListener('click', () => moveVideo(false))
document.getElementById('next-button').addEventListener('click', () => moveVideo(true)) document.getElementById('next-button').addEventListener('click', () => moveVideo(true))
window.addEventListener('hashchange', hashChange, false) window.addEventListener('hashchange', hashChange, false)
// Image hover
const images = document.getElementsByClassName("clickable-img")
for (let i = 0; i < images.length; i++) {
images[i].addEventListener('mouseenter', e => swapImages(e, 'gif'), false)
images[i].addEventListener('mouseout', e => swapImages(e, 'img'), false)
}
hashChange() hashChange()

View file

@ -3,6 +3,12 @@
overflow: hidden; overflow: hidden;
} }
.clickable-img { .hidden {
cursor: pointer; display: none;
}
/* Make gifs take all available space */
.clickable-img img {
width: 100%;
height: 100%;
} }

View file

@ -3,7 +3,7 @@
<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 id="{$item->id}" href="#{$item->id}" class="clickable-img" <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}"
@ -11,12 +11,13 @@
data-video_height="{$item->video->height}" data-video_height="{$item->video->height}"
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" src="{path('stream?url=' . urlencode($item->video->dynamicCover))}" />
</a> </a>
</div> </div>
{/foreach} {/foreach}
</div> </div>
<div class="buttons"> <div n:ifset="$feed->info" class="buttons">
<a n:ifset="$_GET['cursor']" class="button is-danger" href="?cursor=0">First</a> <a n:ifset="$_GET['cursor']" class="button is-danger" href="?cursor=0">First</a>
<a class="button is-danger" href="?cursor={$feed->minCursor}">Back</a> <a class="button is-danger" href="?cursor={$feed->minCursor}">Back</a>
{if $feed->hasMore} {if $feed->hasMore}

View file

@ -0,0 +1,9 @@
<div class="tags">
{if !empty($following)}
{foreach $following as $user}
<span class="tag">{$user}</span>
{/foreach}
{else}
<p>None</p>
{/if}
</div>

View file

@ -10,6 +10,7 @@
<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('settings')}" class="navbar-item">Settings</a> <a href="{path('settings')}" class="navbar-item">Settings</a>
</div> </div>
</div> </div>

View file

@ -0,0 +1,24 @@
{include '../following_tags.latte'}
<form action="./settings/following" method="POST">
<div class="field">
<label class="label">Add / Remove user</label>
<div class="control">
<input name="account" class="input" type="text" />
</div>
</div>
<div class="field">
<div class="control">
<label class="radio">
<input type="radio" name="add">Add
</label>
<label class="radio">
<input type="radio" name="remove">Remove
</label>
</div>
</div>
<div class="field">
<div class="control">
<button class="button is-primary" type="submit">Send</button>
</div>
</div>
</form>

View file

@ -0,0 +1,15 @@
<form action="./settings/proxy" method="POST">
{foreach $proxy_elements as $proxy_element}
<div class="field">
<label class="label">{$proxy_element}</label>
<div class="control">
<input name="{$proxy_element}" class="input" value="{isset($_COOKIE[$proxy_element]) ? $_COOKIE[$proxy_element] : ''}" required />
</div>
</div>
{/foreach}
<div class="field">
<div class="control">
<button class="button is-success" type="submit">Submit</button>
</div>
</div>
</form>

24
views/following.latte Normal file
View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
{include 'components/head.latte', title: 'Following'}
<body>
{include 'components/navbar.latte'}
<section class="hero is-primary">
<div class="hero-body">
<div class="container has-text-centered">
<p class="title">Following</p>
</div>
</div>
</section>
<section class="section">
<p class="title">Following:</p>
{include 'components/following_tags.latte'}
<p>You can add/remove follows on settings</p>
</section>
<hr />
{include 'components/feed.latte'}
{include 'components/footer.latte'}
</body>
</html>

View file

@ -15,21 +15,11 @@
<section class="section"> <section class="section">
<!-- Proxy settings --> <!-- Proxy settings -->
<p class="title">Proxy</p> <p class="title">Proxy</p>
<form action="./settings" method="POST"> {include 'components/settings/proxy.latte'}
{foreach $proxy_elements as $proxy_element} <hr />
<div class="field"> <!-- Following -->
<label class="label">{$proxy_element}</label> <p class="title">Following</p>
<div class="control"> {include 'components/settings/following.latte'}
<input name="{$proxy_element}" class="input" value="{isset($_COOKIE[$proxy_element]) ? $_COOKIE[$proxy_element] : ''}" required />
</div>
</div>
{/foreach}
<div class="field">
<div class="control">
<button class="button is-success" type="submit">Submit</button>
</div>
</div>
</form>
</section> </section>
{include 'components/footer.latte'} {include 'components/footer.latte'}
</body> </body>

View file

@ -8,7 +8,7 @@
<section class="hero is-primary"> <section class="hero is-primary">
<div class="hero-body"> <div class="hero-body">
<div class="container has-text-centered"> <div class="container has-text-centered">
<p class="title">Trending page</p> <p class="title">Trending</p>
</div> </div>
</div> </div>
</section> </section>