Android Matrix messenger application using the Matrix Rust Sdk and Jetpack Compose
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

317 lines
12 KiB

/*
* Copyright (c) 2024 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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();