|
{% extends 'base.html' %}
|
|
|
|
{% block title %}Доступные мне файлы{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="row mb-4">
|
|
<div class="col-md-8">
|
|
<nav aria-label="breadcrumb" class="breadcrumb-container">
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item active">Доступные мне файлы</li>
|
|
</ol>
|
|
</nav>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<form action="{{ url_for('search') }}" method="get" class="search-form">
|
|
<div class="search-container">
|
|
<input type="text" name="query" class="form-control search-input" placeholder="Поиск файлов...">
|
|
<button type="submit" class="search-button"><i class="fas fa-search"></i></button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-md-12">
|
|
<div class="card">
|
|
<div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">Доступные мне файлы</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{% if files %}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>Имя</th>
|
|
<th>Владелец</th>
|
|
<th>Тип</th>
|
|
<th>Права доступа</th>
|
|
<th>Действия</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for file in files %}
|
|
<tr>
|
|
<td>
|
|
{% if file.file_type in ['image', 'video', 'audio'] %}
|
|
<a href="#" class="text-decoration-none" data-bs-toggle="modal" data-bs-target="#mediaModal"
|
|
data-file-type="{{ file.file_type }}"
|
|
data-file-path="{{ url_for('download_file', file_id=file.id) }}"
|
|
data-file-name="{{ file.original_filename }}">
|
|
<i class="fas fa-file text-primary"></i> {{ file.original_filename }}
|
|
</a>
|
|
{% else %}
|
|
<i class="fas fa-file text-primary"></i> {{ file.original_filename }}
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ file.owner }}</td>
|
|
<td>
|
|
{% if file.file_type == 'image' %}
|
|
<i class="fas fa-image text-info"></i> Изображение
|
|
{% elif file.file_type == 'video' %}
|
|
<i class="fas fa-video text-danger"></i> Видео
|
|
{% elif file.file_type == 'audio' %}
|
|
<i class="fas fa-music text-success"></i> Аудио
|
|
{% elif file.file_type == 'text' %}
|
|
<i class="fas fa-file-alt text-secondary"></i> Текст
|
|
{% else %}
|
|
<i class="fas fa-file text-secondary"></i> Файл
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ file.access_type }}</td>
|
|
<td>
|
|
<div class="d-flex gap-2">
|
|
<a href="{{ url_for('download_file', file_id=file.id) }}" class="btn btn-sm btn-primary rounded-circle" title="Скачать">
|
|
<i class="fas fa-download"></i>
|
|
</a>
|
|
{% if file.file_type in ['text', 'code', 'document'] or file.original_filename.endswith(('.txt', '.html', '.css', '.js', '.py', '.md', '.json', '.xml', '.csv')) %}
|
|
{% if file.access_type == 'write' %}
|
|
<button class="btn btn-sm btn-info rounded-circle" title="Редактировать" onclick="openTextEditor('{{ file.id }}', '{{ file.original_filename }}', true)">
|
|
<i class="fas fa-edit"></i>
|
|
</button>
|
|
{% else %}
|
|
<button class="btn btn-sm btn-secondary rounded-circle" title="Просмотреть" onclick="openTextEditor('{{ file.id }}', '{{ file.original_filename }}', false)">
|
|
<i class="fas fa-eye"></i>
|
|
</button>
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center py-5">
|
|
<i class="fas fa-share-alt fa-4x text-muted mb-3"></i>
|
|
<h5>У вас нет доступных файлов</h5>
|
|
<p>Когда другие пользователи поделятся с вами файлами, они появятся здесь.</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="modal fade" id="editModal" tabindex="-1">
|
|
<div class="modal-dialog modal-xl">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Редактор: <span id="editFileName"></span></h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<textarea id="editorContent" class="form-control font-monospace" rows="20"></textarea>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary" onclick="saveChanges()">Сохранить</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="modal fade" id="mediaModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Просмотр файла: <span id="mediaFileName"></span></h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body text-center">
|
|
|
|
<img id="imageViewer" class="img-fluid d-none" alt="Просмотр изображения">
|
|
|
|
|
|
<video id="videoPlayer" class="d-none w-100" controls>
|
|
Ваш браузер не поддерживает воспроизведение видео.
|
|
</video>
|
|
|
|
|
|
<audio id="audioPlayer" class="d-none w-100" controls>
|
|
Ваш браузер не поддерживает воспроизведение аудио.
|
|
</audio>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const mediaModal = document.getElementById('mediaModal');
|
|
mediaModal.addEventListener('show.bs.modal', function(event) {
|
|
const button = event.relatedTarget;
|
|
const fileType = button.getAttribute('data-file-type');
|
|
const filePath = button.getAttribute('data-file-path');
|
|
const fileName = button.getAttribute('data-file-name');
|
|
|
|
document.getElementById('mediaFileName').textContent = fileName;
|
|
|
|
|
|
document.getElementById('imageViewer').classList.add('d-none');
|
|
document.getElementById('videoPlayer').classList.add('d-none');
|
|
document.getElementById('audioPlayer').classList.add('d-none');
|
|
|
|
|
|
if (fileType === 'image') {
|
|
const imageViewer = document.getElementById('imageViewer');
|
|
imageViewer.src = filePath;
|
|
imageViewer.classList.remove('d-none');
|
|
} else if (fileType === 'video') {
|
|
const videoPlayer = document.getElementById('videoPlayer');
|
|
videoPlayer.src = filePath;
|
|
videoPlayer.classList.remove('d-none');
|
|
} else if (fileType === 'audio') {
|
|
const audioPlayer = document.getElementById('audioPlayer');
|
|
audioPlayer.src = filePath;
|
|
audioPlayer.classList.remove('d-none');
|
|
}
|
|
});
|
|
|
|
|
|
mediaModal.addEventListener('hidden.bs.modal', function() {
|
|
document.getElementById('imageViewer').src = '';
|
|
document.getElementById('videoPlayer').src = '';
|
|
document.getElementById('audioPlayer').src = '';
|
|
});
|
|
});
|
|
|
|
|
|
let currentFileId = null;
|
|
|
|
function openTextEditor(fileId, fileName, canEdit) {
|
|
currentFileId = fileId;
|
|
document.getElementById('editFileName').textContent = fileName;
|
|
|
|
|
|
const saveButton = document.querySelector('#editModal .modal-footer .btn-primary');
|
|
const textarea = document.getElementById('editorContent');
|
|
|
|
if (!canEdit) {
|
|
saveButton.style.display = 'none';
|
|
textarea.readOnly = true;
|
|
} else {
|
|
saveButton.style.display = 'block';
|
|
textarea.readOnly = false;
|
|
}
|
|
|
|
|
|
fetch(`/get_file_content/${fileId}`)
|
|
.then(response => response.text())
|
|
.then(content => {
|
|
textarea.value = content;
|
|
const editModal = new bootstrap.Modal(document.getElementById('editModal'));
|
|
editModal.show();
|
|
})
|
|
.catch(error => {
|
|
alert('Ошибка при загрузке файла: ' + error);
|
|
});
|
|
}
|
|
|
|
function saveChanges() {
|
|
if (!currentFileId) return;
|
|
|
|
const content = document.getElementById('editorContent').value;
|
|
|
|
fetch(`/save_file_content/${currentFileId}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ content: content })
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
alert('Файл успешно сохранен!');
|
|
const editModal = bootstrap.Modal.getInstance(document.getElementById('editModal'));
|
|
editModal.hide();
|
|
} else {
|
|
alert('Ошибка при сохранении файла: ' + data.error);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
alert('Ошибка при сохранении файла: ' + error);
|
|
});
|
|
}
|
|
</script>
|
|
{% endblock %} |