コミットを比較

...

3 コミット

作成者 SHA1 メッセージ 日付
守矢諏訪子 48844f985b 再生リスト 2022-02-24 14:01:27 +09:00
守矢諏訪子 e26da1c28c カテゴリ&公開設定 2022-02-24 14:01:19 +09:00
守矢諏訪子 500e44fa51 検索 2022-02-24 13:53:47 +09:00
19個のファイルの変更1023行の追加12行の削除

ファイルの表示

@ -3,8 +3,9 @@ APP_ENV=local
APP_KEY=
APP_DEBUG=false
APP_LOG_LEVEL=debug
APP_URL=http://localhost
ONION_HOST=jkdasfhfdhndsfnklhjfdsknjfdgsjk.onion
APP_URL=https://example.com
ONION_HOST=http://example.onion
I2P_HOST=http://exampe.b32.i2p
SESSION_SECURE_COOKIE=false
SESSION_HTTP_ONLY=true
THEME="techsuwa"
@ -65,4 +66,4 @@ YOUTUBE_API=""
LBRY_URI=""
PEER_URI=""
PEER_USER=""
PEER_PASS=""
PEER_PASS=""

70
app/Http/Controllers/Search.php ノーマルファイル
ファイルの表示

@ -0,0 +1,70 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Common;
// use Illuminate\Support\Facades\Log;
class Search extends Common {
private $common;
private $res;
public $filter = [];
public function __construct () {
$this->common = new Common;
$this->res = [
'page' => 'search',
'style' => 'search',
'userinfo' => $this->common->user,
'version' => $this->common->version,
];
}
public function index (Request $r) {
$this->updateFilter($r->all());
$filter = $this->formatFilter();
$this->res['searchterm'] = $this->filter['search'];
$this->res['res'] = [];
$this->res['res']['video-channels'] = $this->get('video-channels', 0, 2, $filter);
$this->res['res']['video-playlists'] = $this->get('video-playlists', 0, 2, $filter);
$this->res['res']['videos'] = $this->get('videos', 0, 2, $filter);
$this->res['totalres'] = 0;
foreach ($this->res['res'] as $v) $this->res['totalres'] += $v->total;
return view('pages.peertube.search', ['res' => $this->res]);
}
public function updateFilter ($v) {
$this->filter['search'] = isset($v['search']) ? $v['search'] : '';
$this->filter['searchTarget'] = 'local';
$this->filter['sort'] = isset($v['sort']) ? '-'.$v['sort'] : '-match'; // 並び替え、match | publishedAt | views
$this->filter['isLive'] = isset($v['isLive']) ? $v['isLive'] : null; // 表示、null | true | false
$this->filter['nsfw'] = isset($v['nsfw']) ? $v['nsfw'] : null; // センシティブなコンテンツを表示、both | false
$this->filter['startDate'] = isset($v['startDate']) ? $v['startDate'] : null; // 投稿日、null | フォーマット「yyyy-mm-ddT15:00:000Z」
$this->filter['originallyPublishedStartDate'] = isset($v['originallyPublishedStartDate']) ? $v['originallyPublishedStartDate'] : null; // 動画が投稿された年→から、フォーマット「yyyy-12-31T15:00:000.Z」
$this->filter['originallyPublishedEndDate'] = isset($v['originallyPublishedEndDate']) ? $v['originallyPublishedEndDate'] : null; // 動画が投稿された年→まで、フォーマット「yyyy-12-31T15:00:000.Z」
$this->filter['durationMin'] = isset($v['durationMin']) ? $v['durationMin'] : null; // 再生時間、中間の場合240、長いの場合600
$this->filter['durationMax'] = isset($v['durationMax']) ? $v['durationMax'] : null; // 再生時間、短いの場合240、中間の場合600
$this->filter['categoryOneOf'] = isset($v['categoryOneOf']) ? $v['categoryOneOf'] : null; // カテゴリ、カテゴリのINT
$this->filter['licenseOneOf'] = isset($v['licenseOneOf']) ? $v['licenseOneOf'] : null; // ライセンス、ライセンスのINT
$this->filter['languageOneOf'] = isset($v['languageOneOf']) ? $v['languageOneOf'] : null; // 言語、2文字言語コード
$this->filter['tagsOneOf'] = isset($v['tagsOneOf']) ? $v['tagsOneOf'] : null; // これらのタグ全て、単語(複数場合:&tagsOneOf=sa1&tagsOneOf=sa2)
$this->filter['tagsAllOf'] = isset($v['tagsAllOf']) ? $v['tagsAllOf'] : null; // これらのタグのうち1つ、単語(複数場合:&tagsAllOf=sa1&tagsAllOf=sa2)
$this->filter['host'] = isset($v['host']) ? $v['host'] : null; // インスタンス、ドメイン名
}
function formatFilter () {
$filter = '';
foreach ($this->filter as $k => $v) {
if (!is_null($v)) $filter .= '&'.$k.'='.$v;
}
return $filter;
}
function get ($type, $start, $count, $filter) {
return $this->ptapi('/api/v1/search/'.$type.'?start='.$start.'&count='.$count.$filter);
}
}

82
app/Http/Controllers/Watch/Playlist.php ノーマルファイル
ファイルの表示

@ -0,0 +1,82 @@
<?php
namespace App\Http\Controllers\Watch;
use Illuminate\Http\Request;
use App\Http\Controllers\Common;
// use Illuminate\Support\Facades\Log;
class Playlist extends Common {
private $common;
public function __construct () {
$this->common = new Common;
}
public function index ($id, Request $r) {
$res = [
'page' => 'playlist',
'style' => 'watch',
'id' => $id,
'pos' => isset($r->playlistPosition) ? (int)$r->playlistPosition : 1,
'resume' => isset($r->resume) ? (bool)$r->resume : true,
'userinfo' => $this->common->user,
];
$det = $this->getDetail($id);
$res['playlist'] = $det;
$res['plvid'] = $this->getVideos($det->uuid, 0, $det->videosLength);
if ($res['pos'] < 1) $res['pos'] = 1;
if ($res['pos'] > $det->videosLength) $res['pos'] = $det->videosLength;
$id = 0;
foreach ($res['plvid']->data as $k => $v) {
if ($v->position == $res['pos']) {
$id = $v->video->uuid;
$res['detail'] = $this->getVideo($id);
}
$res['plvid']->data[$k]->video->nameShort = strlen($res['plvid']->data[$k]->video->name) > 45 ? substr($res['plvid']->data[$k]->video->name, 0, 45).'...' : $res['plvid']->data[$k]->video->name;
}
$res = $this->getComment($id, $res);
$tags = [];
if (!is_null($res['detail']->tags)) $tags = $res['detail']->tags;
else $tags = explode(' ', $res['detail']->title);
$res['recommend'] = $this->getRecommend($tags);
return view('pages.peertube.w.p', ['res' => $res]);
}
function getDetail ($id) {
return $this->ptapi('/api/v1/video-playlists/'.$id);
}
function getVideos ($uuid, $start, $count) {
return $this->ptapi('/api/v1/video-playlists/'.$uuid.'/videos?start='.$start.'&count='.$count);
}
function getVideo ($uuid) {
return $this->ptapi('/api/v1/videos/'.$uuid);
}
function getRecommend ($tags) {
$tag = '';
foreach ($tags as $t) {
$tag .= 'tagsOneOf='.urlencode($t).'&';
}
return $this->ptapi('/api/v1/search/videos?start=0&count=6&nsfw=both&'.$tag.'sort=-publishedAt&searchTarget=local');
}
function getComment ($id, $res) {
$get = null;
$res['comment'] = $this->ptapi('/api/v1/videos/'.$id.'/comment-threads');
foreach ($res['comment']->data as $co) {
$co->src = 'PT';
}
return $res;
}
}

ファイルの表示

@ -92,4 +92,17 @@ function ptAvatar ($v) {
return '/img/noicon.jpg';
}
function ptPrivacy ($v) {
$res = '不明';
switch ((int)$v) {
case 1: $res = '公開'; break;
case 2: $res = '未収載'; break;
case 3: $res = '非公開'; break;
case 4: $res = 'ローカルのみ'; break;
}
return $res;
}
?>

17
public/css/common.css vendored
ファイルの表示

@ -261,6 +261,20 @@ my-recommended-videos {
max-width: 201px;
}
@media screen and (max-width: 499px) {
.menu-wrapper {
width: 66px !important;
}
.login-buttons-block, .menu-block .block-title, .footer-block .block-title, .publish-button, .publish-button:active, .publish-button:focus {
display: none;
}
.menu-link {
padding-inline-start: 20;
}
}
@media screen and (min-width: 500px) {
.margin-content .videos, .margin-content .playlists {
--miniatureMinWidth: 255px;
@ -990,9 +1004,6 @@ my-notification {
margin-top: 1.5rem;
}
[tabindex="-1"]:focus:not(:focus-visible) {
outline: 0!important;
}
.avatar-32 {
--avatarSize: 32px;
}

318
public/css/search.css vendored ノーマルファイル
ファイルの表示

@ -0,0 +1,318 @@
.search-result {
padding: 40px;
}
.results-header {
font-size: 16px;
padding-bottom: 20px;
margin-bottom: 30px;
border-bottom: 1px solid #DADADA;
}
.results-header .first-line {
display: flex;
flex-direction: row;
}
.results-header .first-line .results-counter {
flex-grow: 1;
}
.mr-1 {
margin-inline-end: .25rem;
}
.mr-1, .mx-1 {
margin-right: .25rem !important;
}
.results-header .first-line .results-counter .search-value {
font-weight: 600;
}
.ml-auto, .mx-auto {
margin-left: auto!important;
}
.results-header .first-line .results-filter-button .icon.icon-filter {
margin-inline-end: 5px;
}
.results-header .first-line .results-filter-button .icon.icon-filter {
display: inline-block;
background-repeat: no-repeat;
background-size: contain;
width: 20px;
height: 20px;
vertical-align: middle;
cursor: pointer;
position: relative;
top: -1px;
background-image: url(filter.c4a7184e9b15e9a9.svg);
}
.collapse-transition {
transition: max-height .3s;
display: block!important;
overflow: hidden!important;
max-height: 0;
}
.form-group {
margin-bottom: 25px;
}
.label-container {
display: flex;
white-space: nowrap;
}
.radio-label {
font-size: 15px;
font-weight: 700;
}
.peertube-radio-container {
margin-inline-end: 30px;
display: inline-block;
}
#custom-css input, #custom-css textarea {
background: var(--inputColor) !important;
color: var(--mainForegroundColor) !important;
border: 1px solid var(--mainBackgroundColor);
}
.peertube-radio-container [type=radio]:checked, .peertube-radio-container [type=radio]:not(:checked) {
position: absolute;
left: -9999px;
}
input[type=radio], input[type=checkbox] {
box-sizing: border-box;
padding: 0;
}
.peertube-radio-container [type=radio]:checked+label, .peertube-radio-container [type=radio]:not(:checked)+label {
position: relative;
padding-left: 28px;
cursor: pointer;
line-height: 20px;
display: inline-block;
font-size: 15px;
font-weight: 400;
}
.pl-0 {
padding-inline-start: 0;
}
.pl-0, .px-0 {
padding-left: 0 !important;
}
@media (min-width: 576px) {
.col-sm-6 {
flex: 0 0 50%;
max-width: 50%;
}
}
.col-uhd, .col-uhd-auto, .col-uhd-12, .col-uhd-11, .col-uhd-10, .col-uhd-9, .col-uhd-8, .col-uhd-7, .col-uhd-6, .col-uhd-5, .col-uhd-4, .col-uhd-3, .col-uhd-2, .col-uhd-1, .col-qhd, .col-qhd-auto, .col-qhd-12, .col-qhd-11, .col-qhd-10, .col-qhd-9, .col-qhd-8, .col-qhd-7, .col-qhd-6, .col-qhd-5, .col-qhd-4, .col-qhd-3, .col-qhd-2, .col-qhd-1, .col-fhd, .col-fhd-auto, .col-fhd-12, .col-fhd-11, .col-fhd-10, .col-fhd-9, .col-fhd-8, .col-fhd-7, .col-fhd-6, .col-fhd-5, .col-fhd-4, .col-fhd-3, .col-fhd-2, .col-fhd-1, .col-xxl, .col-xxl-auto, .col-xxl-12, .col-xxl-11, .col-xxl-10, .col-xxl-9, .col-xxl-8, .col-xxl-7, .col-xxl-6, .col-xxl-5, .col-xxl-4, .col-xxl-3, .col-xxl-2, .col-xxl-1, .col-xl, .col-xl-auto, .col-xl-12, .col-xl-11, .col-xl-10, .col-xl-9, .col-xl-8, .col-xl-7, .col-xl-6, .col-xl-5, .col-xl-4, .col-xl-3, .col-xl-2, .col-xl-1, .col-lg, .col-lg-auto, .col-lg-12, .col-lg-11, .col-lg-10, .col-lg-9, .col-lg-8, .col-lg-7, .col-lg-6, .col-lg-5, .col-lg-4, .col-lg-3, .col-lg-2, .col-lg-1, .col-md, .col-md-auto, .col-md-12, .col-md-11, .col-md-10, .col-md-9, .col-md-8, .col-md-7, .col-md-6, .col-md-5, .col-md-4, .col-md-3, .col-md-2, .col-md-1, .col-sm, .col-sm-auto, .col-sm-12, .col-sm-11, .col-sm-10, .col-sm-9, .col-sm-8, .col-sm-7, .col-sm-6, .col-sm-5, .col-sm-4, .col-sm-3, .col-sm-2, .col-sm-1, .col, .col-auto, .col-12, .col-11, .col-10, .col-9, .col-8, .col-7, .col-6, .col-5, .col-4, .col-3, .col-2, .col-1 {
position: relative;
width: 100%;
padding-right: 15px;
padding-left: 15px;
}
.submit-button {
text-align: end;
}
#custom-css input, #custom-css textarea {
background: var(--inputColor) !important;
color: var(--mainForegroundColor) !important;
border: 1px solid var(--mainBackgroundColor);
}
input[type=text] {
padding: 0 15px;
display: inline-block;
height: 30px;
width: 100%;
color: var(--inputForegroundColor);
background-color: var(--inputBackgroundColor);
border: 1px solid #C6C6C6;
border-radius: 3px;
font-size: 15px;
display: block;
}
#custom-css .peertube-select-container, input[type="text"] {
border: 1px solid var(--mainBackgroundColor) !important;
background: var(--inputColor) !important;
color: var(--mainForegroundColor) !important;
}
.form-control {
font-size: 15px;
color: var(--mainForegroundColor);
background-color: var(--inputBackgroundColor);
outline: none;
}
.form-control {
display: block;
width: 100%;
height: calc(1.5em + 0.75rem + 2px);
padding: .375rem .75rem;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #495057;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ced4da;
border-radius: .25rem;
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
}
input, textarea {
outline: none;
color: var(--inputForegroundColor);
}
button, input {
overflow: visible;
}
input, button, select, optgroup, textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
#custom-css .peertube-select-container, input[type="text"] {
border: 1px solid var(--mainBackgroundColor) !important;
background: var(--inputColor) !important;
color: var(--mainForegroundColor) !important;
}
.peertube-select-container {
padding: 0;
margin: 0 0 1rem;
width: auto;
border-radius: 3px;
color: var(--inputForegroundColor);
background: var(--inputBackgroundColor);
position: relative;
font-size: 15px;
height: min-content;
}
.peertube-select-container select {
padding: 0 35px 0 12px;
position: relative;
border: 1px solid #C6C6C6;
background: transparent none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
cursor: pointer;
height: 30px;
text-overflow: ellipsis;
color: var(--mainForegroundColor);
}
#custom-css .peertube-select-container > select option:hover, #custom-css .peertube-select-container > select > option:checked {
color: var(--whiteColor) !important;
background-color: var(--mainColor) !important;
}
#custom-css .peertube-select-container > select > option {
background: var(--inputColor);
color: var(--mainForegroundColor) !important;
}
#custom-css input, #custom-css textarea {
background: var(--inputColor) !important;
color: var(--mainForegroundColor) !important;
border: 1px solid var(--mainBackgroundColor);
}
input[type=text] {
padding: 0 15px;
display: inline-block;
height: 30px;
width: 100%;
color: var(--inputForegroundColor);
background-color: var(--inputBackgroundColor);
border: 1px solid #C6C6C6;
border-radius: 3px;
font-size: 15px;
display: block;
}
#custom-css .peertube-select-container, input[type="text"] {
border: 1px solid var(--mainBackgroundColor) !important;
background: var(--inputColor) !important;
color: var(--mainForegroundColor) !important;
}
.entry {
display: flex;
margin-bottom: 40px;
max-width: 800px;
}
.video-miniature.display-as-row my-video-thumbnail {
margin-inline-end: 10px;
min-width: var(--rowThumbnailWidth);
max-width: var(--rowThumbnailWidth);
height: var(--rowThumbnailHeight);
}
.video-thumbnail-actions-overlay {
position: absolute;
display: flex;
flex-direction: column;
right: 5px;
top: 5px;
opacity: 0;
}
.video-thumbnail-watch-later-overlay {
padding: 3px;
}
.video-thumbnail-watch-later-overlay, .video-thumbnail-label-overlay, .video-thumbnail-duration-overlay, .video-thumbnail-live-overlay {
display: inline-block;
background-color: #000000b3;
color: #fff;
border-radius: 3px;
font-size: 12px;
font-weight: 600;
line-height: 1.1;
z-index: 10;
}
[role=button] {
cursor: pointer;
}
.video-thumbnail-watch-later-overlay, .video-thumbnail-label-overlay, .video-thumbnail-duration-overlay, .video-thumbnail-live-overlay {
display: inline-block;
background-color: #000000b3;
color: #fff;
border-radius: 3px;
font-size: 12px;
font-weight: 600;
line-height: 1.1;
z-index: 10;
}
.video-miniature.display-as-row .video-bottom {
display: flex;
min-width: 1px;
}

183
public/css/watch.css vendored
ファイルの表示

@ -9,4 +9,185 @@
.avatar-and-textarea my-actor-avatar {
margin-inline-end: 10px;
}
}
.playlist {
min-width: 200px;
max-width: 470px;
height: 66vh;
background-color: var(--mainBackgroundColor);
overflow-y: auto;
border-bottom: 1px solid rgba(0,0,0,.1);
}
.playlist .playlist-info {
padding: 5px 30px;
background-color: #31363b;
}
.playlist .playlist-info .playlist-display-name {
font-size: 18px;
font-weight: 600;
margin-bottom: 5px;
}
.playlist .playlist-info .playlist-by-index {
color: var(--greyForegroundColor);
display: flex;
}
.playlist .playlist-info .playlist-by-index .playlist-by {
margin-inline-end: 5px;
}
.playlist .playlist-info .playlist-controls {
display: flex;
margin: 10px 0;
}
.playlist .playlist-info .playlist-controls my-global-icon:not(:last-child) {
margin-inline-end: .5rem;
}
.playlist .playlist-info .playlist-controls my-global-icon:not(.active) {
opacity: .5;
}
.playlist .playlist-info .playlist-controls my-global-icon {
cursor: pointer;
}
.video {
border-bottom: 1px solid rgba(255,255,255,.1);
color: var(--mainForegroundColor);
display: flex;
min-width: 0;
align-items: center;
cursor: pointer;
}
.video.active {
background-color: var(--mainColor);
}
.video .position {
margin-inline-end: 10px;
font-weight: 600;
color: var(--greyForegroundColor);
min-width: 25px;
}
.playlist my-video-playlist-element-miniature .video .position {
margin-inline-end: 0;
}
my-video-thumbnail, .fake-thumbnail {
margin-inline-end: 10px;
display: flex;
}
.playlist my-video-playlist-element-miniature my-video-thumbnail .video-thumbnail {
width: 90px;
height: 50px;
}
my-video-thumbnail .video-thumbnail {
width: 130px;
height: 72px;
}
.video-thumbnail-loli img {
width: 90px;
height: 50px;
}
.video-thumbnail-label-overlay {
position: absolute;
padding: 0 5px;
left: 5px;
top: 5px;
font-weight: 700;
}
.video-thumbnail-duration-overlay, .video-thumbnail-live-overlay {
position: absolute;
padding: 0 3px;
right: 5px;
bottom: 5px;
}
.video-thumbnail-watch-later-overlay, .video-thumbnail-label-overlay, .video-thumbnail-duration-overlay, .video-thumbnail-live-overlay {
display: inline-block;
background-color: #000000b3;
color: #fff;
border-radius: 3px;
font-size: 12px;
font-weight: 600;
line-height: 1.1;
z-index: 10;
}
.video-thumbnail .play-overlay .icon {
width: 0;
height: 0;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%) scale(.5);
border-top: 13px solid transparent;
border-bottom: 13px solid transparent;
border-left: 18px solid rgba(255,255,255,.95);
}
.video-thumbnail .play-overlay, .video-thumbnail .play-overlay .icon {
transition: all .2s ease;
}
.video-thumbnail .play-overlay {
position: absolute;
right: 0;
bottom: 0;
width: inherit;
height: inherit;
opacity: 0;
background-color: #0000004d;
}
.video .video-info {
display: flex;
flex-direction: column;
align-self: flex-start;
min-width: 0;
}
.video .video-info .video-info-header {
display: flex;
align-self: baseline;
}
.video .video-info .video-info-header a {
color: #fcfcfc;
width: auto;
padding-right: 5px;
}
.playlist my-video-playlist-element-miniature .video .video-info .video-info-name {
font-size: 15px;
}
.video .video-info-name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 18px;
font-weight: 600;
display: inline-block;
}
.video .video-info .video-info-account, .video .video-info .video-info-timestamp {
color: var(--greyForegroundColor);
}
my-global-icon {
width: inherit;
}

ファイルの表示

@ -0,0 +1,16 @@
@foreach ($res['res']['video-channels']->data as $k => $v)
<div class="entry video-channel">
<my-actor-avatar>
<a title="{{ ptFullHandle($v) }} (チャンネルページへ) " href="/c/{{ ptFullHandle($v) }}">
<img class="avatar channel" src="{{ ptAvatar($v) }}" alt="チャンネルのアバター" />
</a>
</my-actor-avatar>
<div class="video-channel-info">
<a class="video-channel-names" href="/c/{{ ptFullHandle($v) }}">
<div class="video-channel-display-name">{{ $v->displayName }}</div>
<div class="video-channel-name">{{ ptFullHandle($v) }}</div>
</a>
<div class="video-channel-followers">チャンネル登録者数 {{ $v->followersCount }}</div>
</div>
</div>
@endforeach

ファイルの表示

@ -0,0 +1,158 @@
<!--div class="results-filter collapse-transition collapse">
<my-search-filters>
<form novalidate="" role="form" class="ng-untouched ng-valid ng-dirty">
<div class="row">
<div class="col-lg-4 col-md-6 col-xs-12">
<div class="form-group">
<div class="radio-label label-container">
<label>並び替え</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="sort" id="-match" class="ng-untouched ng-pristine ng-valid">
<label class="radio" for="-match">関連性</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="sort" id="-publishedAt" class="ng-untouched ng-pristine ng-valid">
<label class="radio" for="-publishedAt">投稿日</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="sort" id="-views" class="ng-untouched ng-pristine ng-valid">
<label class="radio" for="-views">視聴回数</label>
</div>
</div>
<div class="form-group">
<div class="radio-label label-container">
<label>Display only</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="isLive" id="isLiveTrue" value="true" class="ng-untouched ng-pristine ng-valid" />
<label for="isLiveTrue" class="radio">ライブ配信動画</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="isLive" id="isLiveFalse" value="false" class="ng-untouched ng-pristine ng-valid" />
<label for="isLiveFalse" class="radio">ビデオ・オン・デマンド動画</label>
</div>
</div>
<div class="form-group">
<div class="radio-label label-container">
<label>センシティブなコンテンツを表示</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="sensitiveContent" id="sensitiveContentYes" value="both" class="ng-untouched ng-pristine ng-valid" />
<label for="sensitiveContentYes" class="radio">はい</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="sensitiveContent" id="sensitiveContentNo" value="false" class="ng-untouched ng-pristine ng-valid" />
<label for="sensitiveContentNo" class="radio">いいえ</label>
</div>
</div>
<div class="form-group">
<div class="radio-label label-container">
<label>投稿日</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="publishedDateRange" id="today" class="ng-untouched ng-pristine ng-valid" />
<label class="radio" for="today">今日</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="publishedDateRange" id="last_7days" class="ng-untouched ng-pristine ng-valid" />
<label class="radio" for="last_7days">過去7日間</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="publishedDateRange" id="last_30days" class="ng-untouched ng-pristine ng-valid" />
<label class="radio" for="last_30days">過去30日間</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="publishedDateRange" id="last_365days" class="ng-untouched ng-pristine ng-valid" />
<label class="radio" for="last_365days">過去365日間</label>
</div>
</div>
<div class="form-group">
<div class="label-container">
<label for="original-publication-after">動画が投稿された年</label>
</div>
<div class="row">
<div class="pl-0 col-sm-6">
<input type="text" id="original-publication-after" name="original-publication-after" placeholder="後…" class="form-control ng-untouched ng-pristine ng-valid" />
</div>
<div class="pr-0 col-sm-6">
<input type="text" id="original-publication-before" name="original-publication-before" placeholder="前…" class="form-control ng-untouched ng-pristine ng-valid" />
</div>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6 col-xs-12">
<div class="form-group">
<div class="radio-label label-container">
<label>再生時間</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="durationRange" id="short" class="ng-untouched ng-pristine ng-valid" />
<label class="radio" for="short">短い(&lt; 4 )</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="durationRange" id="medium" class="ng-untouched ng-pristine ng-valid" />
<label class="radio" for="medium">中間(4 10 )</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="durationRange" id="long" class="ng-untouched ng-pristine ng-valid" />
<label class="radio" for="long">長い(&gt; 10 )</label>
</div>
</div>
<div class="form-group">
<label for="category">カテゴリ</label>
<div class="peertube-select-container">
<select id="category" name="category" class="form-control ng-untouched ng-pristine ng-valid">
<option value="">全てのカテゴリーを表示</option>
<option value="14">アクティビズム</option>
</select>
</div>
</div>
<div class="form-group">
<label for="licence">ライセンス</label>
<div class="peertube-select-container">
<select id="licence" name="licence" class="form-control ng-untouched ng-pristine ng-valid">
<option value="">全てのライセンスを表示</option>
<option value="1">CC BY (作品を複製、頒布、展示、実演を行うにあたり、著作権者の表示を要求する。)</option>
<option value="2">CC BY-SA (作品を複製、頒布、展示、実演を行うにあたり、著作権者の表示を要求し、作品を改変・変形・加工してできた作品についても、元になった作品と同じライセンスを継承させた上で頒布を認める)</option>
<option value="3">CC BY-ND (作品を複製、頒布、展示、実演を行うにあたり、著作権者の表示を要求し、非営利目的での利用に限定し、いかなる改変も禁止する)</option>
<option value="4">CC BY-NC (作品を複製、頒布、展示、実演を行うにあたり、著作権者の表示を要求し、非営利目的での利用に限定する)</option>
<option value="5">CC BY-NC-SA (作品を複製、頒布、展示、実演を行うにあたり、著作権者の表示を要求し、非営利目的での利用に限定し、作品を改変・変形・加工してできた作品についても、元になった作品と同じライセンスを継承させた上で頒布を認める)</option>
<option value="6">CC BY-NC-ND (作品を複製、頒布、展示、実演を行うにあたり、著作権者の表示を要求し、非営利目的での利用に限定し、いかなる改変も禁止する)</option>
<option value="7">パブリックドメイン公開</option>
</select>
</div>
</div>
<div class="form-group">
<label for="language">言語</label>
<div class="peertube-select-container">
<select id="language" name="language" class="form-control ng-untouched ng-pristine ng-valid">
<option value="">全ての言語の動画を表示</option>
<option value="la">Latin</option>
</select>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6 col-xs-12">
<div class="form-group">
<label for="tagsAllOf">これらのタグすべて</label>
<my-select-tags name="tagsAllOf" labelforid="tagsAllOf" id="tagsAllOf" class="ng-untouched ng-valid ng-dirty">
</my-select-tags>
</div>
<div class="form-group">
<label for="tagsOneOf">これらのタグのうち1つ</label>
<my-select-tags name="tagsOneOf" labelforid="tagsOneOf" id="tagsOneOf" class="ng-untouched ng-valid ng-dirty">
</my-select-tags>
</div>
<div class="form-group">
<label for="host">PeerTube instance host</label>
<input type="text" id="host" name="host" placeholder="example.com" class="form-control ng-untouched ng-pristine ng-valid" />
</div>
</div>
</div>
<div class="submit-button">
<input type="submit" value="フィルタ" />
</div>
</form>
</my-search-filters>
</div-->

ファイルの表示

@ -0,0 +1,28 @@
@foreach ($res['res']['video-playlists']->data as $k => $v)
<div class="entry video-playlist">
<my-video-playlist-miniature>
<div class="miniature display-as-row">
<my-link class="miniature-thumbnail">
<a tabindex="0" href="/w/p/{{ $v->shortUUID }}">
<img alt="" aria-labelledby="{{ $v->displayName }}" src="{{ env('PEER_URI') }}{{ $v->thumbnailPath }}" />
<div class="miniature-playlist-info-overlay">{{ $v->videosLength }}枚動画</div>
<div class="play-overlay">
<div class="icon"></div>
</div>
</a>
</my-link>
<div class="miniature-info">
<my-link tabindex="-1" class="miniature-name">
<a tabindex="-1" href="/w/p/{{ $v->shortUUID }}">{{ $v->displayName }}</a>
</my-link>
<a class="by" href="/c/{{ ptFullHandle($v->videoChannel) }}">
{{ ptFullHandle($v->videoChannel) }}
</a>
<div class="privacy-date">
<span class="updated-at">最近編集:{{ date('Y年m月d日 H:i:s T', strtotime($v->updatedAt)) }}</span>
</div>
</div>
</div>
</my-video-playlist-miniature>
</div>
@endforeach

ファイルの表示

@ -1,6 +1,6 @@
<div class="section videos">
<h1 class="section-title">
<a href="/search?categoryOneOf={{ $res['video']->categories[0]->category->id }}">{{ $res['video']->categories[0]->category->label }}</a>
<a href="/search?categoryOneOf={{ $res['video']->categories[0]->category->id }}">{{ ptGetCatId($res['video']->categories[0]->category->id) }}</a>
</h1>
@foreach ($res['video']->categories[0]->videos as $k => $v)
@include('layout.component.common.videominature')

ファイルの表示

@ -1,13 +1,13 @@
<my-video-attributes>
<div class="attribute">
<span class="attribute-label">公開設定</span>
<span class="attribute-value">{{ $res['detail']->privacy->label }}</span>
<span class="attribute-value">{{ ptPrivacy($res['detail']->privacy->id) }}</span>
</div>
<div class="attribute">
<span class="attribute-label">カテゴリ</span>
@if (is_null($res['detail']->category->id)) <span class="attribute-value">{{ $res['detail']->category->label }}</span>
@else <a class="attribute-value" href="/search?categoryOneOf={{ $res['detail']->category->id }}">{{ $res['detail']->category->label }}</a> @endif
@if (is_null($res['detail']->category->id)) <span class="attribute-value">{{ ptGetCatId($res['detail']->category->id) }}</span>
@else <a class="attribute-value" href="/search?categoryOneOf={{ $res['detail']->category->id }}">{{ ptGetCatId($res['detail']->category->id) }}</a> @endif
</div>
@if (!is_null($res['detail']->originallyPublishedAt))

ファイルの表示

@ -0,0 +1,32 @@
<div id="video-wrapper">
<div id="videojs-wrapper">
<div id="vjs_video_3"
playsinline="true"
tabindex="-1"
lang="ja"
role="region"
aria-label="動画プレーヤー"
translate="no"
style="outline: none;"
>
<video
playsinline="playsinline"
tabindex="-1"
poster="{{ env('PEER_URI') }}{{ $res['detail']->previewPath }}"
style="width: 100%; max-height: 720px;"
controls=""
>
@if (!empty($res['detail']->streamingPlaylists))
@foreach ($res['detail']->streamingPlaylists[0]->files as $k => $v)
<source src="{{ $v->fileUrl }}">
@endforeach
@else
@foreach ($res['detail']->files as $k => $v)
<source src="{{ $v->fileUrl }}">
@endforeach
@endif
</video>
</div>
</div>
@include('layout.component.w.playlist.watchplaylist')
</div>

ファイルの表示

@ -0,0 +1,12 @@
<div class="playlist-info">
<div class="playlist-display-name">
{{ $res['playlist']->displayName }}
<span class="badge badge-info">{{ ptPrivacy($res['playlist']->privacy->id) }}</span>
</div>
<div class="playlist-by-index">
<div class="playlist-by">{{ $res['playlist']->videoChannel->displayName }}</div>
<div class="playlist-index">
{{ $res['pos'] }}/{{ $res['playlist']->videosLength }}
</div>
</div>
</div>

ファイルの表示

@ -0,0 +1,35 @@
@foreach ($res['plvid']->data as $p)
<div class="element-{{ $p->position }}">
<my-video-playlist-element-miniature>
<div class="video{{ $p->position == $res['pos'] ? ' active' : '' }}">
<span style="margin: 4px;">{{ $p->position }}</span>
<my-video-thumbnail>
<a class="video-thumbnail-loli" href="/w/p/{{ $res['id'] }}?playlistPosition={{ $p->position }}&resume=true">
<img alt="" aria-label="{{ $p->video->name }}" src="{{ env('PEER_URI') }}{{ $p->video->thumbnailPath }}" />
<div class="video-thumbnail-duration-overlay">{{ ptDuration($p->video->duration) }}</div>
</a>
</my-video-thumbnail>
<div class="video-info">
<div class="video-info-header">
<a tabindex="-1" class="video-info-name" title="{{ $p->video->name }}" href="/w/p/{{ $res['id'] }}?playlistPosition={{ $p->position }}&resume=true">
{{ $p->video->nameShort }}
</a>
</div>
<span class="video-miniature-created-at-views">
<my-date-toggle>
<span class="date-toggle" title="{{ date('Y/m/d', strtotime($p->video->originallyPublishedAt)) }}">{{ date('Y年m月d日', strtotime($p->video->originallyPublishedAt)) }}</span>
</my-date-toggle>
<span class="views" title="">
<my-video-views-counter>
<span title="">{{ $p->video->views }} 回再生</span>
</my-video-views-counter>
</span>
</span>
<span tabindex="-1" class="video-info-account">{{ $p->video->channel->displayName }}</span>
<span tabindex="-1" class="video-info-timestamp"></span>
</div>
</div>
</my-video-playlist-element-miniature>
</div>
@endforeach

ファイルの表示

@ -0,0 +1,6 @@
<my-video-watch-playlist class="playlist">
<div class="playlist">
@include('layout.component.w.playlist.components.info')
@include('layout.component.w.playlist.components.miniature')
</div>
</my-video-watch-playlist>

ファイルの表示

@ -0,0 +1,30 @@
@extends('layout')
@section('content')
<div id="content" tabindex="-1" class="main-col">
<div class="main-row">
<my-search>
<div class="search-result">
<div class="results-header">
<div class="first-line">
<div class="results-counter">
<span class="mr-1">
こちらのインスタンスでの <span class="search-value">{{ $res['searchterm'] }}</span> の結果数:{{ $res['totalres'] }}
</span>
</div>
<div role="button" aria-controls="collapseBasic" class="results-filter-button ml-auto" aria-expanded="false">
フィルタ
</div>
</div>
</div>
@include('layout.component.search.filters')
@include('layout.component.search.channel')
@include('layout.component.search.playlist')
@foreach ($res['res']['videos']->data as $k => $v)
@include('layout.component.common.videominature')
@endforeach
</div>
</my-search>
</div>
</div>
@endsection

14
resources/views/pages/peertube/w/p.blade.php ノーマルファイル
ファイルの表示

@ -0,0 +1,14 @@
@extends('layout')
@section('content')
<div id="content" tabindex="-1" class="main-col">
<div class="main-row">
<my-video-watch>
<div class="root">
@include('layout.component.w.playlist')
@include('layout.component.w.info')
</div>
</my-video-watch>
</div>
</div>
@endsection

ファイルの表示

@ -7,7 +7,11 @@ Route::get('/home', 'Home@index');
Route::get('/a/{id}/{cat?}/{page?}', 'Account@index');
Route::get('/c/{id}/{cat?}/{page?}', 'Channel@index');
Route::get('/w/{id}', 'Watch@index');
Route::group(['prefix' => 'w'], function () {
Route::get('/{id}', 'Watch@index');
Route::get('/p/{id}', 'Watch\Playlist@index');
});
Route::get('/logout', 'Logout@logout');
Route::group(['prefix' => 'login'], function () {