Templates based on classes, cache custom paths
This commit is contained in:
parent
dde4185ad7
commit
6d6ec109ca
14
.env.example
14
.env.example
|
@ -1,7 +1,11 @@
|
|||
# APP_SUBDIR=/ # Subpath your app is running, defaults to /
|
||||
# APP_CACHE=redis # Cache engine for TikTok Api, (more info on README)
|
||||
# APP_SUBDIR=/ # Subpath your app is running, leave commented for /
|
||||
|
||||
# Redis, used on Helpers\CahceEngines\RedisCache (CHOOSE ONE)
|
||||
# LATTE_CACHE=/tmp/proxitok_api # Path for Latte cache, leave commented for ./cache/latte
|
||||
# API_CACHE=redis # Cache engine for TikTok Api, (more info on README)
|
||||
|
||||
# REDIS_URL=redis://:password@host:port # If using password
|
||||
# REDIS_URL=redis://host:port # If not using password
|
||||
# Redis cache, used on Helpers\CacheEngines\RedisCache (CHOOSE ONE)
|
||||
# API_CACHE_REDIS_URL=redis://:password@host:port # If using password
|
||||
# API_CACHE_REDIS_URL=redis://host:port # If not using password
|
||||
|
||||
# JSON cache, used on Helpers\CacheEngines\JSONCache
|
||||
# API_CACHE_JSON=/tmp/proxitok_api # Path for JSON API Cache, leave commented for ./cache/api
|
||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -2,7 +2,7 @@ node_modules
|
|||
/.env
|
||||
/.vscode
|
||||
/vendor
|
||||
/cache/views/*
|
||||
!/cache/views/.gitkeep
|
||||
/cache/latte/*
|
||||
!/cache/latte/.gitkeep
|
||||
/cache/api/*
|
||||
!/cache/api/.gitkeep
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<footer class="footer">
|
||||
<div class="content">
|
||||
<p class="has-text-centered">
|
||||
<div class="content has-text-centered">
|
||||
<p>
|
||||
Made with <span style="color: #e25555;">♥</span> in <a href="https://github.com/pablouser1/ProxiTok">Github</a>
|
||||
</p>
|
||||
<p>Version: {version()}</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "pablouser1/proxitok",
|
||||
"description": "An alternative frontend for TikTok",
|
||||
"version": "1.1.2",
|
||||
"version": "1.2.0",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"repositories": [
|
||||
{
|
||||
|
@ -18,7 +18,8 @@
|
|||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Helpers\\": "helpers/"
|
||||
"Helpers\\": "helpers/",
|
||||
"Views\\Models\\": "views/models/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,23 +2,30 @@
|
|||
namespace Helpers\CacheEngines;
|
||||
|
||||
class JSONCache {
|
||||
const CACHE_PATH = __DIR__ . '/../../cache/api/';
|
||||
private string $cache_path = __DIR__ . '/../../cache/api';
|
||||
|
||||
function __construct() {
|
||||
if (isset($_ENV['API_CACHE_JSON']) && !empty($_ENV['API_CACHE_JSON'])) {
|
||||
$this->cache_path = $_ENV['API_CACHE_JSON'];
|
||||
}
|
||||
}
|
||||
public function get(string $cache_key): object|false {
|
||||
if (is_file(self::CACHE_PATH . $cache_key . '.json')) {
|
||||
$filename = $this->cache_path . '/' . $cache_key . '.json';
|
||||
if (is_file($filename)) {
|
||||
$time = time();
|
||||
$json_string = file_get_contents(self::CACHE_PATH . $cache_key . '.json');
|
||||
$json_string = file_get_contents($filename);
|
||||
$element = json_decode($json_string);
|
||||
if ($time < $element->expires) {
|
||||
return $element->data;
|
||||
}
|
||||
// Remove file if expired
|
||||
unlink(self::CACHE_PATH . $cache_key . '.json');
|
||||
unlink($filename);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function set(string $cache_key, mixed $data, $timeout = 3600) {
|
||||
file_put_contents(self::CACHE_PATH . $cache_key . '.json', json_encode([
|
||||
file_put_contents($this->cache_path . '/' . $cache_key . '.json', json_encode([
|
||||
'data' => $data,
|
||||
'expires' => time() + $timeout
|
||||
]));
|
||||
|
|
|
@ -25,8 +25,8 @@ class Misc {
|
|||
}
|
||||
}
|
||||
// Cache config
|
||||
if (isset($_ENV['APP_CACHE'])) {
|
||||
switch ($_ENV['APP_CACHE']) {
|
||||
if (isset($_ENV['API_CACHE'])) {
|
||||
switch ($_ENV['API_CACHE']) {
|
||||
case 'json':
|
||||
$cacheEngine = new JSONCache();
|
||||
break;
|
||||
|
@ -54,15 +54,24 @@ class Misc {
|
|||
$subdir = '';
|
||||
}
|
||||
$latte = new \Latte\Engine;
|
||||
$latte->setTempDirectory(__DIR__ . '/../cache/views');
|
||||
$cache_path = isset($_ENV['LATTE_CACHE']) && !empty($_ENV['LATTE_CACHE']) ? $_ENV['LATTE_CACHE'] : __DIR__ . '/../cache/latte';
|
||||
$latte->setTempDirectory($cache_path);
|
||||
|
||||
// -- CUSTOM FUNCTIONS -- //
|
||||
// Import assets
|
||||
$latte->addFunction('assets', function (string $name, string $type) use ($subdir) {
|
||||
$path = "{$subdir}/{$type}/{$name}";
|
||||
return $path;
|
||||
});
|
||||
// Relative path
|
||||
$latte->addFunction('path', function (string $name) use ($subdir) {
|
||||
$path = "{$subdir}/{$name}";
|
||||
return $path;
|
||||
});
|
||||
// Version being used
|
||||
$latte->addFunction('version', function () {
|
||||
return \Composer\InstalledVersions::getVersion('pablouser1/proxitok');
|
||||
});
|
||||
// https://stackoverflow.com/a/36365553
|
||||
$latte->addFunction('number', function (int $x) {
|
||||
if($x > 1000) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
use Helpers\Following;
|
||||
use Helpers\Misc;
|
||||
use Steampixel\Route;
|
||||
use Views\Models\FollowingTemplate;
|
||||
|
||||
// Showing
|
||||
Route::add('/following', function () {
|
||||
|
@ -28,9 +29,5 @@ Route::add('/following', function () {
|
|||
'hasMore' => false
|
||||
];
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('following'), [
|
||||
'following' => $following,
|
||||
'feed' => $feed,
|
||||
'title' => 'Following'
|
||||
]);
|
||||
$latte->render(Misc::getView('following'), new FollowingTemplate($following, $feed));
|
||||
});
|
||||
|
|
|
@ -2,18 +2,22 @@
|
|||
require __DIR__ . '/assets.php';
|
||||
require __DIR__ . '/settings.php';
|
||||
require __DIR__ . '/following.php';
|
||||
|
||||
use Steampixel\Route;
|
||||
use Helpers\Misc;
|
||||
use Helpers\Error;
|
||||
use Views\Models\BaseTemplate;
|
||||
use Views\Models\FeedTemplate;
|
||||
use Views\Models\ItemTemplate;
|
||||
|
||||
Route::add('/', function () {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('home'), ['title' => 'Home']);
|
||||
$latte->render(Misc::getView('home'), new BaseTemplate('Home'));
|
||||
});
|
||||
|
||||
Route::add('/about', function () {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('about'), ['title' => 'About']);
|
||||
$latte->render(Misc::getView('about'), new BaseTemplate('About'));
|
||||
});
|
||||
|
||||
Route::add("/trending", function () {
|
||||
|
@ -25,10 +29,7 @@ Route::add("/trending", function () {
|
|||
$feed = $api->getTrendingFeed($cursor);
|
||||
if ($feed->meta->success) {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('trending'), [
|
||||
'feed' => $feed,
|
||||
'title' => 'Trending'
|
||||
]);
|
||||
$latte->render(Misc::getView('trending'), new FeedTemplate('Trending', $feed));
|
||||
} else {
|
||||
Error::show($feed->meta);
|
||||
}
|
||||
|
@ -47,10 +48,7 @@ Route::add("/@([^/]+)", function (string $username) {
|
|||
return 'Private account detected! Not supported';
|
||||
}
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('user'), [
|
||||
'feed' => $feed,
|
||||
'title' => $feed->info->detail->user->nickname
|
||||
]);
|
||||
$latte->render(Misc::getView('user'), new FeedTemplate($feed->info->detail->user->nickname, $feed));
|
||||
} else {
|
||||
Error::show($feed->meta);
|
||||
}
|
||||
|
@ -61,10 +59,7 @@ Route::add('/video/([^/]+)', function (string $video_id) {
|
|||
$item = $api->getVideoByID($video_id);
|
||||
if ($item->meta->success) {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('video'), [
|
||||
'item' => $item,
|
||||
'title' => $item->info->detail->user->nickname
|
||||
]);
|
||||
$latte->render(Misc::getView('video'), new ItemTemplate($item->info->detail->user->nickname, $item));
|
||||
} else {
|
||||
Error::show($item->meta);
|
||||
}
|
||||
|
@ -80,10 +75,7 @@ Route::add('/music/([^/]+)', function (string $music_id) {
|
|||
$feed = $api->getMusicFeed($music_id, $cursor);
|
||||
if ($feed->meta->success) {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('music'), [
|
||||
'feed' => $feed,
|
||||
'title' => 'Music'
|
||||
]);
|
||||
$latte->render(Misc::getView('music'), new FeedTemplate('Music', $feed));
|
||||
} else {
|
||||
Error::show($feed->meta);
|
||||
}
|
||||
|
@ -98,10 +90,7 @@ Route::add('/tag/(\w+)', function (string $name) {
|
|||
$feed = $api->getChallengeFeed($name, $cursor);
|
||||
if ($feed->meta->success) {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('tag'), [
|
||||
'feed' => $feed,
|
||||
'title' => 'Tag'
|
||||
]);
|
||||
$latte->render(Misc::getView('tag'), new FeedTemplate('Tag', $feed));
|
||||
} else {
|
||||
Error::show($feed->meta);
|
||||
}
|
||||
|
|
|
@ -3,15 +3,12 @@
|
|||
use Helpers\Following;
|
||||
use Helpers\Settings;
|
||||
use Helpers\Misc;
|
||||
use Views\Models\SettingsTemplate;
|
||||
use Steampixel\Route;
|
||||
|
||||
Route::add("/settings", function () {
|
||||
$latte = Misc::latte();
|
||||
$latte->render(Misc::getView('settings'), [
|
||||
"proxy_elements" => Settings::PROXY,
|
||||
"following" => Following::get(),
|
||||
"title" => "Settings"
|
||||
]);
|
||||
$latte->render(Misc::getView('settings'), new SettingsTemplate());
|
||||
});
|
||||
|
||||
Route::add("/settings/proxy", function () {
|
||||
|
|
|
@ -33,9 +33,9 @@ bulmaswatch@^0.8.1:
|
|||
integrity sha512-7HGm5v9If6gzxbTht4/oVS0dhySp6g/JyTrxmpSXHXgDQXivvxiuVmcJOZo3PFv9GAOn4om7SK36I2V8W81sgw==
|
||||
|
||||
"chokidar@>=3.0.0 <4.0.0":
|
||||
version "3.5.2"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
|
||||
integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
|
||||
dependencies:
|
||||
anymatch "~3.1.2"
|
||||
braces "~3.0.2"
|
||||
|
@ -113,18 +113,18 @@ readdirp@~3.6.0:
|
|||
picomatch "^2.2.1"
|
||||
|
||||
sass@^1.46.0:
|
||||
version "1.48.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.48.0.tgz#b53cfccc1b8ab4be375cc54f306fda9d4711162c"
|
||||
integrity sha512-hQi5g4DcfjcipotoHZ80l7GNJHGqQS5LwMBjVYB/TaT0vcSSpbgM8Ad7cgfsB2M0MinbkEQQPO9+sjjSiwxqmw==
|
||||
version "1.49.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.0.tgz#65ec1b1d9a6bc1bae8d2c9d4b392c13f5d32c078"
|
||||
integrity sha512-TVwVdNDj6p6b4QymJtNtRS2YtLJ/CqZriGg0eIAbAKMlN8Xy6kbv33FsEZSF7FufFFM705SQviHjjThfaQ4VNw==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
"source-map-js@>=0.6.2 <2.0.0":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf"
|
||||
integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{layout '../layouts/default.latte'}
|
||||
|
||||
{block header}
|
||||
<p class="title">About</p>
|
||||
<p class="title">About</p>
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{layout '../layouts/hero.latte'}
|
||||
|
||||
{block content}
|
||||
<p class="title">There was an error processing your request!</p>
|
||||
<p class="subtitle">HTTP Code: {$error->http_code}</p>
|
||||
{if $error->tiktok_code}
|
||||
<p class="subtitle">API error code {$error->tiktok_code} ({$error->tiktok_msg})</p>
|
||||
{/if}
|
||||
<p class="title">There was an error processing your request!</p>
|
||||
<p class="subtitle">HTTP Code: {$error->http_code}</p>
|
||||
{if $error->tiktok_code}
|
||||
<p class="subtitle">API error code {$error->tiktok_code} ({$error->tiktok_msg})</p>
|
||||
{/if}
|
||||
{/block}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{layout '../layouts/default.latte'}
|
||||
|
||||
{block header}
|
||||
<p class="title">Following</p>
|
||||
<p class="title">Following</p>
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
|
|
104
views/home.latte
104
views/home.latte
|
@ -1,58 +1,58 @@
|
|||
{layout '../layouts/hero.latte'}
|
||||
|
||||
{block content}
|
||||
<p class="title">Welcome to ProxiTok!</p>
|
||||
<p class="subtitle">An alternative open source frontend for TikTok</p>
|
||||
<p>Search user:</p>
|
||||
<form id="username_form">
|
||||
<div class="field has-addons has-addons-centered">
|
||||
<div class="control">
|
||||
<input name="username" class="input" type="text" placeholder="Type username" required />
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button is-success" type="submit">Go</button>
|
||||
</div>
|
||||
</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">
|
||||
<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>
|
||||
<p class="title">Welcome to ProxiTok!</p>
|
||||
<p class="subtitle">An alternative open source frontend for TikTok</p>
|
||||
<p>Search user:</p>
|
||||
<form id="username_form">
|
||||
<div class="field has-addons has-addons-centered">
|
||||
<div class="control">
|
||||
<input name="username" class="input" type="text" placeholder="Type username" required />
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button is-success" type="submit">Go</button>
|
||||
</div>
|
||||
</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">
|
||||
<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}
|
||||
|
|
14
views/models/BaseTemplate.php
Normal file
14
views/models/BaseTemplate.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
namespace Views\Models;
|
||||
|
||||
/**
|
||||
* Base for all templates, needs a Title to set
|
||||
*/
|
||||
class BaseTemplate {
|
||||
public string $title;
|
||||
public string $version;
|
||||
|
||||
function __construct(string $title) {
|
||||
$this->title = $title;
|
||||
}
|
||||
}
|
14
views/models/FeedTemplate.php
Normal file
14
views/models/FeedTemplate.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
namespace Views\Models;
|
||||
|
||||
/**
|
||||
* Base for templates with a feed
|
||||
*/
|
||||
class FeedTemplate extends BaseTemplate {
|
||||
public object $feed;
|
||||
|
||||
function __construct(string $title, object $feed) {
|
||||
parent::__construct($title);
|
||||
$this->feed = $feed;
|
||||
}
|
||||
}
|
14
views/models/FollowingTemplate.php
Normal file
14
views/models/FollowingTemplate.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
namespace Views\Models;
|
||||
|
||||
/**
|
||||
* Exclusive for /following
|
||||
*/
|
||||
class FollowingTemplate extends FeedTemplate {
|
||||
public array $following;
|
||||
|
||||
function __construct(array $following, object $feed) {
|
||||
parent::__construct('Following', $feed);
|
||||
$this->following = $following;
|
||||
}
|
||||
}
|
14
views/models/ItemTemplate.php
Normal file
14
views/models/ItemTemplate.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
namespace Views\Models;
|
||||
|
||||
/**
|
||||
* Base for templates with item (only /video at the time)
|
||||
*/
|
||||
class ItemTemplate extends BaseTemplate {
|
||||
public object $item;
|
||||
|
||||
function __construct(string $title, object $item) {
|
||||
parent::__construct($title);
|
||||
$this->item = $item;
|
||||
}
|
||||
}
|
19
views/models/SettingsTemplate.php
Normal file
19
views/models/SettingsTemplate.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
namespace Views\Models;
|
||||
|
||||
use \Helpers\Following;
|
||||
use \Helpers\Settings;
|
||||
|
||||
/**
|
||||
* Exclusive for /settings
|
||||
*/
|
||||
class SettingsTemplate extends BaseTemplate {
|
||||
public array $proxy_elements = [];
|
||||
public array $following = [];
|
||||
|
||||
function __construct() {
|
||||
parent::__construct('Settings');
|
||||
$this->proxy_elements = Settings::PROXY;
|
||||
$this->following = Following::get();
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
{layout '../layouts/default.latte'}
|
||||
|
||||
{block header}
|
||||
<p class="title">{$feed->info->detail->music->title}</p>
|
||||
<p class="subtitle">{$feed->info->detail->music->desc}</p>
|
||||
<p>Videos: {number($feed->info->detail->stats->videoCount)}</p>
|
||||
<p class="title">{$feed->info->detail->music->title}</p>
|
||||
<p class="subtitle">{$feed->info->detail->music->desc}</p>
|
||||
<p>Videos: {number($feed->info->detail->stats->videoCount)}</p>
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
{layout '../layouts/default.latte'}
|
||||
|
||||
{block header}
|
||||
<p class="title">Settings</p>
|
||||
<p class="title">Settings</p>
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
<!-- Proxy settings -->
|
||||
<p class="title">Proxy</p>
|
||||
{include '../components/settings/proxy.latte'}
|
||||
<hr />
|
||||
<!-- Following -->
|
||||
<p class="title">Following</p>
|
||||
{include '../components/settings/following.latte'}
|
||||
<!-- Proxy settings -->
|
||||
<p class="title">Proxy</p>
|
||||
{include '../components/settings/proxy.latte'}
|
||||
<hr />
|
||||
<!-- Following -->
|
||||
<p class="title">Following</p>
|
||||
{include '../components/settings/following.latte'}
|
||||
{/block}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{layout '../layouts/default.latte'}
|
||||
|
||||
{block header}
|
||||
<p class="title">{$feed->info->detail->challenge->title}</p>
|
||||
<p class="subtitle">{$feed->info->detail->challenge->desc}</p>
|
||||
<p>Videos: {number($feed->info->detail->stats->videoCount)} / Views: {number($feed->info->detail->stats->viewCount)}</p>
|
||||
<p class="title">{$feed->info->detail->challenge->title}</p>
|
||||
<p class="subtitle">{$feed->info->detail->challenge->desc}</p>
|
||||
<p>Videos: {number($feed->info->detail->stats->videoCount)} / Views: {number($feed->info->detail->stats->viewCount)}</p>
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{layout '../layouts/default.latte'}
|
||||
|
||||
{block header}
|
||||
<p class="title">Trending</p>
|
||||
<p class="title">Trending</p>
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{layout '../layouts/default.latte'}
|
||||
|
||||
{block header}
|
||||
<figure class="figure is-96x96">
|
||||
<img src="{path('stream?url=' . urlencode($feed->info->detail->user->avatarThumb))}" />
|
||||
</figure>
|
||||
<p class="title">{$feed->info->detail->user->uniqueId}'s profile</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>Hearts: {number($feed->info->detail->stats->heartCount)} / Videos: {$feed->info->detail->stats->videoCount}</p>
|
||||
<figure class="figure is-96x96">
|
||||
<img src="{path('stream?url=' . urlencode($feed->info->detail->user->avatarThumb))}" />
|
||||
</figure>
|
||||
<p class="title">{$feed->info->detail->user->uniqueId}'s profile</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>Hearts: {number($feed->info->detail->stats->heartCount)} / Videos: {$feed->info->detail->stats->videoCount}</p>
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
{layout '../layouts/hero.latte'}
|
||||
|
||||
{block content}
|
||||
<div class="columns is-centered is-vcentered">
|
||||
<div class="column">
|
||||
<video autoplay controls src="{path('stream?url=' . urlencode($item->items[0]->video->playAddr))}"></video>
|
||||
</div>
|
||||
<div class="column has-text-centered">
|
||||
<div class="box">
|
||||
<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 class="columns is-centered is-vcentered">
|
||||
<div class="column">
|
||||
<video autoplay controls src="{path('stream?url=' . urlencode($item->items[0]->video->playAddr))}"></video>
|
||||
</div>
|
||||
<div class="column has-text-centered">
|
||||
<div class="box">
|
||||
<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>
|
||||
{/block}
|
||||
|
|
Loading…
Reference in a new issue