forked from dsutanto/bChot-android
First Commit
This commit is contained in:
1543
screenshots/html/data.js
Normal file
1543
screenshots/html/data.js
Normal file
File diff suppressed because it is too large
Load Diff
164
screenshots/html/screenshots.css
Normal file
164
screenshots/html/screenshots.css
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
html {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: InterHosted, sans-serif;
|
||||
margin: 0px;
|
||||
background: #F0F0F0;
|
||||
}
|
||||
|
||||
table, td, th {
|
||||
border: 2px solid white;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 0 auto;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0px;
|
||||
background: #DDD;
|
||||
}
|
||||
|
||||
td.view-header {
|
||||
background: #0DBD8B;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
img {
|
||||
padding: 2px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.missing {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #0DBD8B;
|
||||
}
|
||||
|
||||
br {
|
||||
display: block;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
#form_container {
|
||||
margin: 0px auto;
|
||||
}
|
||||
|
||||
form {
|
||||
}
|
||||
|
||||
label {
|
||||
margin-left: 10px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
input {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
#width_input {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
#screenshots_container {
|
||||
overflow: scroll;
|
||||
position: absolute;
|
||||
top: 64px;
|
||||
bottom: 40px;
|
||||
width: 100%;
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.screenshot {
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#header, #footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
background: #101318;
|
||||
color: #FFF;
|
||||
padding: 0px;
|
||||
}
|
||||
#header {
|
||||
top: 0;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.element-logo {
|
||||
display: flex;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.main-title {
|
||||
margin-left: 48px;
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.fullstop--green {
|
||||
margin-left: -2px;
|
||||
color: #0DBD8B;
|
||||
font-family: Extratype eina02;
|
||||
}
|
||||
|
||||
.issue-links {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.issue-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#footer {
|
||||
bottom: 0;
|
||||
text-align: center;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
a:link {
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
text-decoration: none;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.img-link {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
margin-left: 4px;
|
||||
float: left;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
309
screenshots/html/script.js
Normal file
309
screenshots/html/script.js
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
* Copyright 2024, 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
import { screenshots } from './data.js';
|
||||
|
||||
const URL_PARAM_LANGUAGES = "l";
|
||||
const URL_PARAM_IMAGE_WIDTH = "w";
|
||||
const URL_PARAM_ALL_SCREENSHOTS = "a";
|
||||
const URL_PARAM_IF_MODIFIED_AFTER = "d";
|
||||
|
||||
// Get the base url of the current page
|
||||
const baseUrl = window.location.href.split('/').slice(0, -1).join('/');
|
||||
// On localhost, get the English screenshots from the location `../tests/uitests/src/test/snapshots/images`
|
||||
const isLocalHost = window.location.hostname === "localhost"
|
||||
let englishBasePath
|
||||
if (isLocalHost) {
|
||||
englishBasePath = `../tests/uitests/src/test/snapshots/images`
|
||||
} else {
|
||||
englishBasePath = `en`
|
||||
}
|
||||
|
||||
const dataLanguages = screenshots[0];
|
||||
|
||||
// Read the URL params
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
// Get the wanted languages from the url params, or default to "de" and "fr", and ensure "en" is always there
|
||||
const wantedLanguages = (urlParams.get(URL_PARAM_LANGUAGES) ? urlParams.get(URL_PARAM_LANGUAGES).split(',') : ['de', 'fr']) + ["en"];
|
||||
// Map dataLanguages to visibleLanguages, set to 1 if the language is in wantedLanguages, 0 otherwise
|
||||
let visibleLanguages = dataLanguages.map((language) => wantedLanguages.includes(language) ? 1 : 0);
|
||||
// Read width from the url params, and ensure it's a multiple of 25 and is between 75 and 500
|
||||
const DEFAULT_WIDTH = 300;
|
||||
const MIN_WIDTH = 75;
|
||||
const MAX_WIDTH = 500;
|
||||
const WIDTH_STEP = 25;
|
||||
let imageWidth = DEFAULT_WIDTH
|
||||
let width = urlParams.get(URL_PARAM_IMAGE_WIDTH);
|
||||
if (width) {
|
||||
// Ensure width is an integer, if not use the default value
|
||||
width = parseInt(width) || DEFAULT_WIDTH;
|
||||
imageWidth = Math.max(MIN_WIDTH, Math.min(MAX_WIDTH, Math.round(width / WIDTH_STEP) * WIDTH_STEP));
|
||||
}
|
||||
// Read showAllScreenshots from the url params
|
||||
let showAllScreenshots = urlParams.get(URL_PARAM_ALL_SCREENSHOTS) === 1;
|
||||
// Read the minimum date of modification from the url params
|
||||
let minModifiedDayTime = urlParams.get(URL_PARAM_IF_MODIFIED_AFTER);
|
||||
|
||||
function updatePageUrl() {
|
||||
// Update the URL displayed in the browser without loading again the page
|
||||
var queryParams = new URLSearchParams(window.location.search);
|
||||
// Add the languages to the url params, without "en"
|
||||
const lg = dataLanguages.filter((language, i) => visibleLanguages[i] == 1).filter(l => l != "en").join(',');
|
||||
if (lg) {
|
||||
queryParams.set(URL_PARAM_LANGUAGES, lg);
|
||||
} else {
|
||||
queryParams.delete(URL_PARAM_LANGUAGES);
|
||||
}
|
||||
if (imageWidth != DEFAULT_WIDTH) {
|
||||
queryParams.set(URL_PARAM_IMAGE_WIDTH, imageWidth);
|
||||
} else {
|
||||
queryParams.delete(URL_PARAM_IMAGE_WIDTH);
|
||||
}
|
||||
if (showAllScreenshots) {
|
||||
queryParams.set(URL_PARAM_ALL_SCREENSHOTS, showAllScreenshots ? 1 : 0);
|
||||
} else {
|
||||
queryParams.delete(URL_PARAM_ALL_SCREENSHOTS);
|
||||
}
|
||||
if (minModifiedDayTime > 0) {
|
||||
queryParams.set(URL_PARAM_IF_MODIFIED_AFTER, minModifiedDayTime);
|
||||
} else {
|
||||
queryParams.delete(URL_PARAM_IF_MODIFIED_AFTER);
|
||||
}
|
||||
// Replace the current URL with the new one, including the fragment
|
||||
history.replaceState(null, '', `${window.location.pathname}?${queryParams}${window.location.hash}`);
|
||||
}
|
||||
|
||||
function addForm() {
|
||||
// Insert the form into the div with id form_container
|
||||
const form = document.createElement('form');
|
||||
const languageLabel = document.createElement('label');
|
||||
languageLabel.textContent = 'Languages:';
|
||||
form.appendChild(languageLabel);
|
||||
// Add a check box per entry in the dataLanguages
|
||||
for (let i = 0; i < dataLanguages.length; i++){
|
||||
const label = document.createElement('label');
|
||||
const text = document.createTextNode(dataLanguages[i]);
|
||||
const input = document.createElement('input');
|
||||
input.type = 'checkbox';
|
||||
input.disabled = i == 0;
|
||||
input.name = dataLanguages[i];
|
||||
input.checked = visibleLanguages[i] == 1;
|
||||
input.onchange = (e) => {
|
||||
if (e.target.checked) {
|
||||
visibleLanguages[i] = 1;
|
||||
} else {
|
||||
visibleLanguages[i] = 0;
|
||||
}
|
||||
updatePageUrl()
|
||||
addTable();
|
||||
};
|
||||
label.appendChild(input);
|
||||
label.appendChild(text);
|
||||
form.appendChild(label);
|
||||
}
|
||||
// Add a break line
|
||||
form.appendChild(document.createElement('br'));
|
||||
// Add a label with the text "Width"
|
||||
const label = document.createElement('label');
|
||||
label.textContent = 'Screenshots width:';
|
||||
form.appendChild(label);
|
||||
// Add a input text to input the width of the image
|
||||
const widthInput = document.createElement('input');
|
||||
widthInput.id = 'width_input';
|
||||
widthInput.type = 'number';
|
||||
widthInput.min = MIN_WIDTH;
|
||||
widthInput.max = MAX_WIDTH;
|
||||
widthInput.step = WIDTH_STEP;
|
||||
widthInput.value = imageWidth;
|
||||
widthInput.onchange = (e) => {
|
||||
imageWidth = e.target.value;
|
||||
updatePageUrl();
|
||||
addTable();
|
||||
};
|
||||
form.appendChild(widthInput);
|
||||
// Add a label with the text "Show all screenshots"
|
||||
const label2 = document.createElement('label');
|
||||
label2.textContent = 'Show all screenshots:';
|
||||
label2.title = 'Show all screenshots, including those with no translated versions.';
|
||||
const input2 = document.createElement('input');
|
||||
input2.type = 'checkbox';
|
||||
input2.name = "test";
|
||||
input2.checked = showAllScreenshots;
|
||||
input2.onchange = (e) => {
|
||||
showAllScreenshots = e.target.checked;
|
||||
updatePageUrl()
|
||||
addTable();
|
||||
};
|
||||
label2.appendChild(input2);
|
||||
form.appendChild(label2);
|
||||
/*
|
||||
// Add a date picker to input the minimum date of modification
|
||||
const label3 = document.createElement('label');
|
||||
label3.textContent = 'If modified since:';
|
||||
form.appendChild(label3);
|
||||
const dateInput = document.createElement('input');
|
||||
dateInput.type = 'date';
|
||||
if (minModifiedDayTime > 0) {
|
||||
dateInput.value = new Date(minModifiedDayTime * 86400000).toISOString().split('T')[0];
|
||||
}
|
||||
dateInput.onchange = (e) => {
|
||||
if (e.target.value === "") {
|
||||
minModifiedDayTime = 0;
|
||||
} else {
|
||||
minModifiedDayTime = new Date(e.target.value).getTime() / 86400000;
|
||||
}
|
||||
updatePageUrl();
|
||||
addTable();
|
||||
};
|
||||
form.appendChild(dateInput);
|
||||
*/
|
||||
// Add a span with id result to display the number of lines
|
||||
const lines = document.createElement('span');
|
||||
lines.id = 'lines';
|
||||
lines.textContent = "...";
|
||||
form.appendChild(lines);
|
||||
document.getElementById('form_container').appendChild(form);
|
||||
}
|
||||
|
||||
function getNiceName(name) {
|
||||
var indices = [];
|
||||
for(var i = 0; i < name.length; i++) {
|
||||
if (name[i] === "_") indices.push(i);
|
||||
}
|
||||
return name.substring(indices[0] + 1, indices[1]);
|
||||
}
|
||||
|
||||
function createMissingImageElement() {
|
||||
const text = document.createElement('p');
|
||||
text.className = "missing";
|
||||
text.textContent = 'No image';
|
||||
return text;
|
||||
}
|
||||
|
||||
function createUpToDateImageElement() {
|
||||
const text = document.createElement('p');
|
||||
text.className = "missing";
|
||||
text.textContent = 'Image not updated';
|
||||
return text;
|
||||
}
|
||||
|
||||
function convertToHumanReadableDate(modifiedDayTime) {
|
||||
var date = new Date(modifiedDayTime * 86400000);
|
||||
return date.toLocaleDateString();
|
||||
}
|
||||
|
||||
function createImageElement(fullFile, modifiedDayTime) {
|
||||
const img = document.createElement('img');
|
||||
img.className = "screenshot";
|
||||
img.src = `${baseUrl}/${fullFile}`;
|
||||
if(modifiedDayTime > 0) {
|
||||
img.title = fullFile + "\n\nModified on " + convertToHumanReadableDate(modifiedDayTime);
|
||||
} else {
|
||||
img.title = fullFile;
|
||||
}
|
||||
img.alt = "Missing image";
|
||||
img.width = imageWidth;
|
||||
return img;
|
||||
}
|
||||
|
||||
function addTable() {
|
||||
var linesCounter = 0;
|
||||
// Remove any previous table
|
||||
document.getElementById('screenshots_container').innerHTML = '';
|
||||
// screenshots contains a table of screenshots, lets convert to an html table
|
||||
const table = document.createElement('table');
|
||||
const thead = document.createElement('thead');
|
||||
const tbody = document.createElement('tbody');
|
||||
|
||||
// First item of screenshots contains the languages
|
||||
// Build the languages row
|
||||
const languagesHeaderRow = document.createElement('tr');
|
||||
for (let languageIndex = 0; languageIndex < dataLanguages.length; languageIndex++) {
|
||||
// Do not add the language if it is hidden
|
||||
if (visibleLanguages[languageIndex] == 0) {
|
||||
continue;
|
||||
}
|
||||
const th = document.createElement('th');
|
||||
th.textContent = dataLanguages[languageIndex];
|
||||
languagesHeaderRow.appendChild(th);
|
||||
}
|
||||
const numVisibleLanguages = languagesHeaderRow.childElementCount
|
||||
// Next items are the data
|
||||
var currentHeaderValue = "";
|
||||
var screenshotCounter = 0;
|
||||
for (let screenshotIndex = 1; screenshotIndex < screenshots.length; screenshotIndex++) {
|
||||
let englishFile = screenshots[screenshotIndex][0];
|
||||
let niceName = getNiceName(englishFile);
|
||||
if (niceName != currentHeaderValue) {
|
||||
screenshotCounter = 0;
|
||||
}
|
||||
const tr = document.createElement('tr');
|
||||
tr.id = niceName + screenshotCounter;
|
||||
let hasTranslatedFiles = false;
|
||||
for (let languageIndex = 0; languageIndex < dataLanguages.length; languageIndex++) {
|
||||
if (visibleLanguages[languageIndex] == 0) {
|
||||
continue;
|
||||
}
|
||||
const td = document.createElement('td');
|
||||
if (languageIndex == 0) {
|
||||
// English file
|
||||
td.appendChild(createImageElement(`${englishBasePath}/${englishFile}.png`, 0));
|
||||
} else if (languageIndex == 1) {
|
||||
// Dark English file
|
||||
if (screenshots[screenshotIndex][1].length > 0) {
|
||||
hasTranslatedFiles = true;
|
||||
td.appendChild(createImageElement(`${englishBasePath}/${screenshots[screenshotIndex][1]}.png`, 0));
|
||||
} else {
|
||||
td.appendChild(createMissingImageElement());
|
||||
}
|
||||
} else {
|
||||
let modifiedDayTime = screenshots[screenshotIndex][languageIndex];
|
||||
if (modifiedDayTime === 0) {
|
||||
td.appendChild(createMissingImageElement());
|
||||
} else if(modifiedDayTime >= minModifiedDayTime) {
|
||||
hasTranslatedFiles = true;
|
||||
// Foreign file is the same as the english file, replacing the language
|
||||
const foreignFile = englishFile.substring(0, englishFile.length-2) + dataLanguages[languageIndex];
|
||||
const fullForeignFile = `${dataLanguages[languageIndex]}/${foreignFile}.png`;
|
||||
td.appendChild(createImageElement(fullForeignFile, modifiedDayTime));
|
||||
} else {
|
||||
td.appendChild(createUpToDateImageElement());
|
||||
}
|
||||
}
|
||||
tr.appendChild(td);
|
||||
}
|
||||
if (showAllScreenshots || hasTranslatedFiles) {
|
||||
linesCounter++;
|
||||
// Add a header for row, if different from previous
|
||||
if (niceName != currentHeaderValue) {
|
||||
currentHeaderValue = niceName;
|
||||
const trHead = document.createElement('tr');
|
||||
trHead.id = niceName;
|
||||
const tdHead = document.createElement('td');
|
||||
tdHead.colSpan = numVisibleLanguages;
|
||||
tdHead.className = "view-header";
|
||||
tdHead.textContent = niceName;
|
||||
trHead.appendChild(tdHead);
|
||||
tbody.appendChild(trHead);
|
||||
tbody.appendChild(languagesHeaderRow.cloneNode(true));
|
||||
}
|
||||
tbody.appendChild(tr);
|
||||
}
|
||||
screenshotCounter++;
|
||||
}
|
||||
table.appendChild(thead);
|
||||
table.appendChild(tbody);
|
||||
|
||||
// Add the table to the div with id screenshots_container
|
||||
document.getElementById('screenshots_container').appendChild(table);
|
||||
// Update the number of lines
|
||||
document.getElementById('lines').textContent = `${linesCounter} lines`;
|
||||
}
|
||||
|
||||
addForm();
|
||||
addTable();
|
||||
Reference in New Issue
Block a user