Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
b667c3f
Rename PageSection Area to Zone and update references
Denis-RZ Jun 17, 2025
328b489
Merge pull request #101 from Denis-RZ/codex/rename-area-property-to-zone
Denis-RZ Jun 17, 2025
8dacfcb
Read layout zones from config
Denis-RZ Jun 17, 2025
5d2c354
Merge pull request #102 from Denis-RZ/codex/externalize-layout-zones-…
Denis-RZ Jun 17, 2025
a2bbdbd
Render markdown sections
Denis-RZ Jun 17, 2025
26e4500
Merge pull request #103 from Denis-RZ/codex/add-markdown-rendering-to…
Denis-RZ Jun 17, 2025
22d4947
Move section editor partial to shared
Denis-RZ Jun 17, 2025
730995d
Merge pull request #104 from Denis-RZ/codex/unify-section-editors-int…
Denis-RZ Jun 17, 2025
0971a56
Task 4: Unify SectionEditor — single shared Quill partial
Denis-RZ Jun 17, 2025
b86d9a5
Merge pull request #105 from Denis-RZ/codex/unify-sectioneditor-parti…
Denis-RZ Jun 17, 2025
5fdd3ea
Add drag-and-drop sorting for admin page sections
Denis-RZ Jun 17, 2025
4b663b8
Merge pull request #106 from Denis-RZ/codex/add-drag-and-drop-sorting…
Denis-RZ Jun 17, 2025
1143b2d
Merge remote-tracking branch 'origin/ndmn4k-codex/rename-area-propert…
Denis-RZ Jun 17, 2025
ce7c6d3
Merge commit '88cb6ce64b0869ac968a7b028b734db218d99f02'
Denis-RZ Jun 17, 2025
57d2a43
Merge pull request #108 from Denis-RZ/ndmn4k-codex/rename-area-proper…
Denis-RZ Jun 17, 2025
7a530fa
Remove merge artifacts and fix build
Denis-RZ Jun 17, 2025
422a489
Merge pull request #110 from Denis-RZ/codex/resolve-code-conflicts-an…
Denis-RZ Jun 17, 2025
e74ee30
Run dotnet format for whitespace
Denis-RZ Jun 17, 2025
ca75e15
Merge pull request #111 from Denis-RZ/codex/resolve-code-conflicts-an…
Denis-RZ Jun 17, 2025
2edafdb
Fix JsonSerializer usage in PageEditor
Denis-RZ Jun 17, 2025
126a792
Merge pull request #112 from Denis-RZ/codex/fix-runtimebinderexceptio…
Denis-RZ Jun 17, 2025
000648c
Refactor content editors and endpoints
Denis-RZ Jun 17, 2025
aaeccd5
Merge pull request #113 from Denis-RZ/codex/clean-up-code-duplication…
Denis-RZ Jun 17, 2025
52e84d3
Enhance page editor zones
Denis-RZ Jun 17, 2025
4809cb0
Merge pull request #114 from Denis-RZ/codex/enhance-visual-feedback-f…
Denis-RZ Jun 17, 2025
e5a3bd9
Add block library panel with drag-and-drop
Denis-RZ Jun 17, 2025
ac0e0bc
Merge pull request #115 from Denis-RZ/codex/implement-visual-block-li…
Denis-RZ Jun 17, 2025
cdcfbcb
Add live preview mode to page editor
Denis-RZ Jun 17, 2025
a62bc88
Merge pull request #116 from Denis-RZ/codex/add-live-preview-function…
Denis-RZ Jun 17, 2025
5f893c5
Refactor section editor scripts
Denis-RZ Jun 18, 2025
7c9b292
Merge pull request #117 from Denis-RZ/codex/fix-critical-architectura…
Denis-RZ Jun 18, 2025
e41f34a
Add role management and permission filtering
Denis-RZ Jun 18, 2025
261656d
Merge pull request #118 from Denis-RZ/codex/fix-role-based-block-visi…
Denis-RZ Jun 18, 2025
709d4b3
Ensure role tables exist for SQLite
Denis-RZ Jun 18, 2025
ef6eb3c
Merge pull request #119 from Denis-RZ/codex/fix-role-based-block-visi…
Denis-RZ Jun 18, 2025
9ebea34
Add role selection for pages and blocks
Denis-RZ Jun 18, 2025
f6b8828
Merge pull request #120 from Denis-RZ/codex/add-role-element-to-block…
Denis-RZ Jun 18, 2025
33f67fc
Fix role dropdown and default anonymous role
Denis-RZ Jun 18, 2025
abbfef5
Merge pull request #121 from Denis-RZ/codex/add-role-element-to-block…
Denis-RZ Jun 18, 2025
de7379a
Enhance admin block UI
Denis-RZ Jun 18, 2025
dee14c4
Merge pull request #122 from Denis-RZ/codex/enhance-block-management-…
Denis-RZ Jun 18, 2025
a3a0789
Integrate block assignment into edit
Denis-RZ Jun 18, 2025
8ddaf46
Merge branch 'main' into fx1uyp-codex/enhance-block-management-interface
Denis-RZ Jun 18, 2025
dc05abc
Merge pull request #123 from Denis-RZ/fx1uyp-codex/enhance-block-mana…
Denis-RZ Jun 18, 2025
e71c813
Add zone dropdowns for block templates
Denis-RZ Jun 18, 2025
aa1d681
Merge pull request #124 from Denis-RZ/codex/add-dropdown-for-pages-an…
Denis-RZ Jun 18, 2025
92d7f02
Fix zone sort retrieval
Denis-RZ Jun 18, 2025
181dc72
Merge pull request #125 from Denis-RZ/b2z994-codex/add-dropdown-for-p…
Denis-RZ Jun 18, 2025
da0d919
Preserve block assignment selections
Denis-RZ Jun 18, 2025
24320c1
Merge pull request #126 from Denis-RZ/codex/fix-ui-and-backend-issues…
Denis-RZ Jun 18, 2025
05add87
Fix tests to use seeded data
Denis-RZ Jun 18, 2025
58e9621
Merge pull request #127 from Denis-RZ/codex/fix-ui-and-backend-issues…
Denis-RZ Jun 18, 2025
30b1f2a
Fix dropdown selections in block templates
Denis-RZ Jun 18, 2025
31b75a5
Merge pull request #128 from Denis-RZ/codex/fix-dropdown-selection-an…
Denis-RZ Jun 23, 2025
0238833
Fix UI issues
Denis-RZ Jun 28, 2025
6462c02
Merge pull request #129 from Denis-RZ/codex/locate-ui-issues-and-repo…
Denis-RZ Jun 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions TEST_PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Test Plan

1. **Build and restore dependencies**
- Run `./setup.sh` to restore NuGet and client libraries.
- Ensure the command completes without errors.

2. **Run unit tests**
- Execute `dotnet test website/MyWebApp.sln`.
- All tests should pass.

3. **Manual UI smoke test**
- Start the application with `dotnet run --project website/MyWebApp`.
- Verify admin pages load correctly:
- Create and edit pages and sections using the unified section editor.
- Insert blocks via the updated API endpoints.
- Confirm media uploads still work and page layouts render as before.

54 changes: 27 additions & 27 deletions extension/html/drive-auth.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<!DOCTYPE html>
<html lang="ru">
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Загрузка в Google Drive</title>
<title>Upload to Google Drive</title>
<style>
body { font-family: Arial, sans-serif; background: #f8f9fa; margin: 0; }
#popup {
Expand Down Expand Up @@ -34,19 +34,19 @@
<body>
<div id="popup">
<button class="close" onclick="window.close()">×</button>
<h2>Загрузка в Google Drive</h2>
<div id="step-auth">
<button id="btn-auth">Авторизоваться в Google</button>
<div class="status" id="auth-status"></div>
</div>
<div id="step-file" style="display:none">
<label>Выберите видеофайл для загрузки (до 10 ГБ):<br>
<input type="file" id="file-input" accept="video/*">
</label>
<h2>Upload to Google Drive</h2>
<div id="step-auth">
<button id="btn-auth">Authorize with Google</button>
<div class="status" id="auth-status"></div>
</div>
<div id="step-file" style="display:none">
<label>Select a video file to upload (up to 10GB):<br>
<input type="file" id="file-input" accept="video/*">
</label>
<div class="status" id="file-status"></div>
</div>
<div id="step-upload" style="display:none">
<div>Загрузка файла в Google Drive...</div>
<div id="step-upload" style="display:none">
<div>Uploading file to Google Drive...</div>
<div class="progress"><div class="progress-bar" id="progress-bar"></div></div>
<div class="status" id="upload-status"></div>
</div>
Expand All @@ -57,7 +57,7 @@ <h2>Загрузка в Google Drive</h2>
let accessToken = '';
let fileToUpload = null;

// 1. Авторизация Google OAuth 2.0 (response_type=token)
// 1. Google OAuth 2.0 Authorization (response_type=token)
document.getElementById('btn-auth').onclick = function() {
const redirectUri = window.location.origin + window.location.pathname;
const url =
Expand All @@ -70,42 +70,42 @@ <h2>Загрузка в Google Drive</h2>
window.location.href = url;
};

// 2. После авторизации получаем access_token из URL
// 2. After authorization get access_token from URL
window.addEventListener('DOMContentLoaded', () => {
const hash = window.location.hash;
if (hash && hash.includes('access_token=')) {
const params = new URLSearchParams(hash.substring(1));
accessToken = params.get('access_token');
document.getElementById('step-auth').style.display = 'none';
document.getElementById('step-file').style.display = '';
document.getElementById('auth-status').textContent = 'Авторизация успешна!';
document.getElementById('auth-status').textContent = 'Authorization successful!';
}
});

// 3. Выбор файла
// 3. File selection
const fileInput = document.getElementById('file-input');
fileInput.onchange = function() {
if (!fileInput.files.length) return;
fileToUpload = fileInput.files[0];
document.getElementById('file-status').textContent = 'Файл выбран: ' + fileToUpload.name + ' (' + (fileToUpload.size/1024/1024).toFixed(2) + ' МБ)';
document.getElementById('file-status').textContent = 'File selected: ' + fileToUpload.name + ' (' + (fileToUpload.size/1024/1024).toFixed(2) + ' MB)';
uploadFile();
};

// 4. Загрузка файла в Google Drive
// 4. Upload file to Google Drive
function uploadFile() {
if (!accessToken || !fileToUpload) return;
document.getElementById('step-file').style.display = 'none';
document.getElementById('step-upload').style.display = '';
const progressBar = document.getElementById('progress-bar');
const uploadStatus = document.getElementById('upload-status');

// Используем Resumable Upload для больших файлов
// Use Resumable Upload for large files
const metadata = {
name: fileToUpload.name,
mimeType: fileToUpload.type
};

// 1. Инициализация сессии загрузки
// 1. Initialize upload session
fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable', {
method: 'POST',
headers: {
Expand All @@ -115,12 +115,12 @@ <h2>Загрузка в Google Drive</h2>
body: JSON.stringify(metadata)
})
.then(res => {
if (!res.ok) throw new Error('Ошибка инициализации загрузки: ' + res.status);
if (!res.ok) throw new Error('Upload initialization error: ' + res.status);
return res.headers.get('Location');
})
.then(uploadUrl => {
if (!uploadUrl) throw new Error('Не получен upload URL');
// 2. Загружаем файл чанками (10 МБ)
if (!uploadUrl) throw new Error('Upload URL not received');
// 2. Upload the file in chunks (10 MB)
const chunkSize = 10 * 1024 * 1024;
let offset = 0;
function uploadChunk() {
Expand All @@ -135,15 +135,15 @@ <h2>Загрузка в Google Drive</h2>
})
.then(res => {
if (res.status === 308) {
// Продолжаем загрузку
// Continue uploading
offset += chunkSize;
progressBar.style.width = Math.min(100, (offset/fileToUpload.size)*100) + '%';
uploadChunk();
} else if (res.ok) {
progressBar.style.width = '100%';
uploadStatus.textContent = '✅ Файл успешно загружен в Google Drive!';
uploadStatus.textContent = '✅ File uploaded to Google Drive!';
} else {
throw new Error('Ошибка загрузки: ' + res.status);
throw new Error('Upload error: ' + res.status);
}
})
.catch(err => {
Expand Down
46 changes: 23 additions & 23 deletions extension/html/folder-picker.html
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,11 @@ <h3>📋 Folder Selection Benefits:</h3>
startIn: 'downloads'
});

showResult(
<strong>✅ Folder Selected Successfully!</strong><br>
<strong>Location:</strong> {dirHandle.name}<br>
<em>Your recordings will now be saved in this folder</em>
);
showResult(
`<strong>✅ Folder Selected Successfully!</strong><br>
<strong>Location:</strong> ${dirHandle.name}<br>
<em>Your recordings will now be saved in this folder</em>`
);

// Send back to extension
if (chrome && chrome.runtime && chrome.runtime.sendMessage) {
Expand All @@ -172,33 +172,33 @@ <h3>📋 Folder Selection Benefits:</h3>
}, 3000);

} else {
showResult(
<strong>⚠️ Browser Limitation</strong><br>
Folder selection is not supported in this browser version.<br>
<em>Recordings will be saved to the Downloads folder.</em>
, false);
showResult(
`<strong>⚠️ Browser Limitation</strong><br>
Folder selection is not supported in this browser version.<br>
<em>Recordings will be saved to the Downloads folder.</em>`,
false);
}
} catch (err) {
if (err.name === 'AbortError') {
showResult(
<strong>📂 Folder Selection Cancelled</strong><br>
<em>No folder was selected. Using default Downloads folder.</em>
, false);
showResult(
`<strong>📂 Folder Selection Cancelled</strong><br>
<em>No folder was selected. Using default Downloads folder.</em>`,
false);
} else {
showResult(
<strong>❌ Error Selecting Folder</strong><br>
<em>{err.message}</em><br>
Using default Downloads folder instead.
, false);
showResult(
`<strong>❌ Error Selecting Folder</strong><br>
<em>${err.message}</em><br>
Using default Downloads folder instead.`,
false);
}
}
};

document.getElementById('useDefault').onclick = () => {
showResult(
<strong>📥 Using Default Downloads Folder</strong><br>
<em>All recordings will be saved to your Downloads folder</em>
);
showResult(
`<strong>📥 Using Default Downloads Folder</strong><br>
<em>All recordings will be saved to your Downloads folder</em>`
);

// Send back to extension
if (chrome && chrome.runtime && chrome.runtime.sendMessage) {
Expand Down
131 changes: 1 addition & 130 deletions extension/html/privacy-policy.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,136 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Privacy Policy - Screen Area Recorder Pro</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #333;
max-width: 900px;
margin: 0 auto;
padding: 20px;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
}
.container {
background: white;
padding: 40px;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
border: 1px solid rgba(255,255,255,0.2);
}
h1 {
color: #2c3e50;
border-bottom: 4px solid #3498db;
padding-bottom: 15px;
font-size: 2.2em;
margin-bottom: 10px;
}
h2 {
color: #34495e;
margin-top: 35px;
border-left: 5px solid #3498db;
padding-left: 20px;
font-size: 1.4em;
}
h3 {
color: #2c3e50;
margin-top: 25px;
font-size: 1.2em;
}
.highlight {
background: linear-gradient(135deg, #e8f4fd 0%, #c8e6f5 100%);
padding: 20px;
border-radius: 8px;
border-left: 5px solid #3498db;
margin: 25px 0;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.warning {
background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
padding: 20px;
border-radius: 8px;
border-left: 5px solid #f39c12;
margin: 25px 0;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.success {
background: linear-gradient(135deg, #d4edda 0%, #a8e6cf 100%);
padding: 20px;
border-radius: 8px;
border-left: 5px solid #27ae60;
margin: 25px 0;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
ul, ol {
margin: 15px 0;
padding-left: 30px;
}
li {
margin: 8px 0;
line-height: 1.5;
}
.last-updated {
font-style: italic;
color: #7f8c8d;
text-align: center;
margin-bottom: 30px;
background: #ecf0f1;
padding: 10px;
border-radius: 5px;
}
.contact-info {
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
padding: 25px;
border-radius: 8px;
margin: 30px 0;
border: 1px solid #dee2e6;
}
.emoji {
font-size: 1.2em;
margin-right: 8px;
}
.table-container {
overflow-x: auto;
margin: 20px 0;
}
table {
width: 100%;
border-collapse: collapse;
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
th, td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
background: #3498db;
color: white;
font-weight: 600;
}
.privacy-feature {
display: flex;
align-items: center;
margin: 10px 0;
padding: 10px;
background: #f8f9fa;
border-radius: 5px;
}
.check {
color: #27ae60;
font-size: 1.3em;
margin-right: 10px;
}
.cross {
color: #e74c3c;
font-size: 1.3em;
margin-right: 10px;
}
</style>
<link rel="stylesheet" href="../styles/privacy-policy.css">
</head>
<body>
<div class="container">
Expand Down
Loading
Loading