mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
Stuff i guess ?
This commit is contained in:
118
public/css/app.css
Normal file
118
public/css/app.css
Normal file
@@ -0,0 +1,118 @@
|
||||
.items,
|
||||
.item {
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
.items .item,
|
||||
.item .item {
|
||||
margin: 20px;
|
||||
width: 120px;
|
||||
height: 180px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 5px 10px rgba(0,0,0,0.8);
|
||||
transform-origin: center top;
|
||||
transform-style: preserve-3d;
|
||||
transform: translateZ(0);
|
||||
transition: 0.3s;
|
||||
}
|
||||
.items .item img,
|
||||
.item .item img {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
.items .item figcaption,
|
||||
.item .item figcaption {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 20px;
|
||||
padding-bottom: 10px;
|
||||
font-size: 20px;
|
||||
background: none;
|
||||
color: #fff;
|
||||
transform: translateY(100%);
|
||||
transition: 0.3s;
|
||||
}
|
||||
.items .item:after,
|
||||
.item .item:after {
|
||||
content: '';
|
||||
z-index: 10;
|
||||
width: 200%;
|
||||
height: 100%;
|
||||
top: -90%;
|
||||
left: -20px;
|
||||
opacity: 0.1;
|
||||
transform: rotate(45deg);
|
||||
background: linear-gradient(to top, transparent, #fff 15%, rgba(255,255,255,0.5));
|
||||
transition: 0.3s;
|
||||
}
|
||||
.items .item:hover,
|
||||
.item .item:hover,
|
||||
.items .item:focus,
|
||||
.item .item:focus,
|
||||
.items .item:active,
|
||||
.item .item:active {
|
||||
box-shadow: 0 8px 16px 3px rgba(0,0,0,0.6);
|
||||
transform: translateY(-3px) scale(1.05) rotateX(15deg);
|
||||
}
|
||||
.items .item:hover figcaption,
|
||||
.item .item:hover figcaption,
|
||||
.items .item:focus figcaption,
|
||||
.item .item:focus figcaption,
|
||||
.items .item:active figcaption,
|
||||
.item .item:active figcaption {
|
||||
transform: none;
|
||||
}
|
||||
.items .item:hover:after,
|
||||
.item .item:hover:after,
|
||||
.items .item:focus:after,
|
||||
.item .item:focus:after,
|
||||
.items .item:active:after,
|
||||
.item .item:active:after {
|
||||
transform: rotate(25deg);
|
||||
top: -40%;
|
||||
opacity: 0.15;
|
||||
}
|
||||
.item .article {
|
||||
overflow: hidden;
|
||||
width: 350px;
|
||||
height: 235px;
|
||||
margin: 20px;
|
||||
}
|
||||
.item .article img {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
transition: 0.2s;
|
||||
}
|
||||
.item .article figcaption {
|
||||
font-size: 14px;
|
||||
text-shadow: 0 1px 0 rgba(51,51,51,0.3);
|
||||
color: #fff;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
padding: 40px;
|
||||
box-shadow: 0 0 2px rgba(0,0,0,0.2);
|
||||
background: rgba(6,18,53,0.6);
|
||||
opacity: 0;
|
||||
transform: scale(1.15);
|
||||
transition: 0.2s;
|
||||
}
|
||||
.item .article figcaption h3 {
|
||||
color: #3792e3;
|
||||
font-size: 16px;
|
||||
margin-bottom: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
.item .article:hover img,
|
||||
.item .article:focus img,
|
||||
.item .article:active img {
|
||||
filter: blur(3px);
|
||||
transform: scale(0.97);
|
||||
}
|
||||
.item .article:hover figcaption,
|
||||
.item .article:focus figcaption,
|
||||
.item .article:active figcaption {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
@@ -263,13 +263,13 @@ $container->set(\App\Controllers\SettingsController::class, function ($c) {
|
||||
return new \App\Controllers\SettingsController($c->get(PDO::class), $c->get('view'));
|
||||
});
|
||||
|
||||
// Register PlayniteImportController
|
||||
$container->set(\App\Controllers\PlayniteImportController::class, function ($c) {
|
||||
return new \App\Controllers\PlayniteImportController(
|
||||
$c->get(PDO::class),
|
||||
$c->get('view'),
|
||||
$c->get(\App\Services\AuthService::class)
|
||||
);
|
||||
// Register API controllers
|
||||
$container->set(\App\Controllers\Api\PlayniteController::class, function ($c) {
|
||||
return new \App\Controllers\Api\PlayniteController($c->get(PDO::class));
|
||||
});
|
||||
|
||||
$container->set(\App\Controllers\Api\AuthController::class, function ($c) {
|
||||
return new \App\Controllers\Api\AuthController($c->get(\App\Services\AuthService::class));
|
||||
});
|
||||
|
||||
// Register PlayniteImportService
|
||||
@@ -298,6 +298,69 @@ $app = AppFactory::create();
|
||||
$twig = $container->get('view');
|
||||
$app->add(TwigMiddleware::create($app, $twig));
|
||||
|
||||
// PHP DebugBar Setup (only in development)
|
||||
if ($_ENV['APP_DEBUG'] === 'true') {
|
||||
$debugbar = new \DebugBar\StandardDebugBar();
|
||||
|
||||
// Set up the debug bar renderer with the correct base URL
|
||||
$baseUrl = rtrim($app->getBasePath(), '/');
|
||||
$debugbarRenderer = $debugbar->getJavascriptRenderer($baseUrl . '/phpdebugbar');
|
||||
|
||||
// Add DebugBar to Twig globals
|
||||
$twig->getEnvironment()->addGlobal('debugbarRenderer', $debugbarRenderer);
|
||||
|
||||
// Add route to serve DebugBar assets
|
||||
$app->get('/phpdebugbar/{path:.*}', function ($request, $response, $args) use ($debugbar) {
|
||||
$debugbarRenderer = $debugbar->getJavascriptRenderer();
|
||||
$path = $args['path'];
|
||||
|
||||
// Serve CSS files
|
||||
if (preg_match('/\.css$/', $path)) {
|
||||
$content = file_get_contents($debugbarRenderer->getBasePath() . '/' . $path);
|
||||
$response->getBody()->write($content);
|
||||
return $response->withHeader('Content-Type', 'text/css');
|
||||
}
|
||||
|
||||
// Serve JS files
|
||||
if (preg_match('/\.js$/', $path)) {
|
||||
$content = file_get_contents($debugbarRenderer->getBasePath() . '/' . $path);
|
||||
$response->getBody()->write($content);
|
||||
return $response->withHeader('Content-Type', 'application/javascript');
|
||||
}
|
||||
|
||||
// Serve other assets (fonts, etc.)
|
||||
$content = @file_get_contents($debugbarRenderer->getBasePath() . '/' . $path);
|
||||
if ($content !== false) {
|
||||
$response->getBody()->write($content);
|
||||
return $response;
|
||||
}
|
||||
|
||||
return $response->withStatus(404);
|
||||
});
|
||||
|
||||
// Add middleware to collect data
|
||||
$app->add(function ($request, $handler) use ($debugbar) {
|
||||
// Start timing the request
|
||||
$debugbar['time']->startMeasure('app', 'Application');
|
||||
|
||||
try {
|
||||
$response = $handler->handle($request);
|
||||
|
||||
// Stop timing if it was started
|
||||
if ($debugbar['time']->hasStartedMeasure('app')) {
|
||||
$debugbar['time']->stopMeasure('app');
|
||||
}
|
||||
|
||||
return $response;
|
||||
} catch (\Exception $e) {
|
||||
// Make sure to stop timing even if an exception occurs
|
||||
if ($debugbar['time']->hasStartedMeasure('app')) {
|
||||
$debugbar['time']->stopMeasure('app');
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
});
|
||||
}
|
||||
// Add Error Middleware
|
||||
$errorMiddleware = $app->addErrorMiddleware(
|
||||
$_ENV['APP_DEBUG'] === 'true',
|
||||
@@ -307,5 +370,6 @@ $errorMiddleware = $app->addErrorMiddleware(
|
||||
|
||||
// Register routes
|
||||
require __DIR__ . '/../routes/web.php';
|
||||
require __DIR__ . '/../routes/api.php';
|
||||
|
||||
$app->run();
|
||||
|
||||
125
public/js/adult-video-actors.js
Normal file
125
public/js/adult-video-actors.js
Normal file
@@ -0,0 +1,125 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const videoId = document.getElementById('video-id').value;
|
||||
const actorSearch = document.getElementById('actor-search');
|
||||
const actorResults = document.getElementById('actor-results');
|
||||
const actorsList = document.getElementById('actors-list');
|
||||
|
||||
// Debounce search
|
||||
let searchTimeout;
|
||||
actorSearch.addEventListener('input', function(e) {
|
||||
clearTimeout(searchTimeout);
|
||||
const query = e.target.value.trim();
|
||||
|
||||
if (query.length < 2) {
|
||||
actorResults.innerHTML = '';
|
||||
actorResults.classList.add('d-none');
|
||||
return;
|
||||
}
|
||||
|
||||
searchTimeout = setTimeout(() => {
|
||||
searchActors(query);
|
||||
}, 300);
|
||||
});
|
||||
|
||||
// Search for actors
|
||||
function searchActors(query) {
|
||||
fetch(`/admin/adult-videos/search-actors?q=${encodeURIComponent(query)}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
actorResults.innerHTML = '';
|
||||
|
||||
if (data.data && data.data.length > 0) {
|
||||
data.data.forEach(actor => {
|
||||
const item = document.createElement('div');
|
||||
item.className = 'list-group-item list-group-item-action';
|
||||
item.textContent = actor.name;
|
||||
item.addEventListener('click', () => addActorToVideo(actor.id, actor.name));
|
||||
actorResults.appendChild(item);
|
||||
});
|
||||
actorResults.classList.remove('d-none');
|
||||
} else {
|
||||
const noResults = document.createElement('div');
|
||||
noResults.className = 'list-group-item';
|
||||
noResults.textContent = 'No actors found';
|
||||
actorResults.appendChild(noResults);
|
||||
actorResults.classList.remove('d-none');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Add actor to video
|
||||
function addActorToVideo(actorId, actorName) {
|
||||
fetch(`/admin/adult-videos/${videoId}/actors`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
body: JSON.stringify({ actor_id: actorId })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
addActorToList(actorId, actorName);
|
||||
actorSearch.value = '';
|
||||
actorResults.innerHTML = '';
|
||||
actorResults.classList.add('d-none');
|
||||
} else {
|
||||
alert('Failed to add actor: ' + (data.error || 'Unknown error'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Add actor to the UI list
|
||||
function addActorToList(actorId, actorName) {
|
||||
const item = document.createElement('div');
|
||||
item.className = 'd-flex justify-content-between align-items-center mb-2';
|
||||
item.dataset.actorId = actorId;
|
||||
item.innerHTML = `
|
||||
<span>${actorName}</span>
|
||||
<button type="button" class="btn btn-sm btn-danger remove-actor" data-actor-id="${actorId}">
|
||||
<i class="fas fa-times"></i> Remove
|
||||
</button>
|
||||
`;
|
||||
actorsList.appendChild(item);
|
||||
|
||||
// Add event listener to the remove button
|
||||
item.querySelector('.remove-actor').addEventListener('click', () => removeActor(actorId, item));
|
||||
}
|
||||
|
||||
// Remove actor from video
|
||||
function removeActor(actorId, element) {
|
||||
if (confirm('Are you sure you want to remove this actor?')) {
|
||||
fetch(`/admin/adult-videos/${videoId}/actors/${actorId}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
element.remove();
|
||||
} else {
|
||||
alert('Failed to remove actor: ' + (data.error || 'Unknown error'));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Load existing actors
|
||||
function loadActors() {
|
||||
fetch(`/admin/adult/${videoId}/actors`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.data && data.data.length > 0) {
|
||||
data.data.forEach(actor => {
|
||||
addActorToList(actor.id, actor.name);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize
|
||||
loadActors();
|
||||
});
|
||||
Reference in New Issue
Block a user