Merge branch 'main' into v2

* main:
  build: use specific token for pushing release tags
  fix(gui): update `uncamel()` to handle strings like 'IDs' (fixes #10128) (#10131)
  refactor: use slices package for sort (#10132)
  build: process for automatic release tags (#10133)
  chore(gui, man, authors): update docs, translations, and contributors
This commit is contained in:
Jakob Borg
2025-05-26 14:22:30 +02:00
51 changed files with 375 additions and 115 deletions
+32 -20
View File
@@ -1,27 +1,39 @@
angular.module('syncthing.core')
.filter('uncamel', function () {
const reservedStrings = [
'IDs', 'ID', // substrings must come AFTER longer keywords containing them
'URL', 'UR',
'API', 'QUIC', 'TCP', 'UDP', 'NAT', 'LAN', 'WAN',
'KiB', 'MiB', 'GiB', 'TiB'
];
return function (input) {
input = input.replace(/(.)([A-Z][a-z]+)/g, '$1 $2').replace(/([a-z0-9])([A-Z])/g, '$1 $2');
var parts = input.split(' ');
var lastPart = parts.splice(-1)[0];
if (!input || typeof input !== 'string') return '';
const placeholders = {};
let counter = 0;
reservedStrings.forEach(word => {
const placeholder = `__RSV${counter}__`;
const re = new RegExp(word, 'g');
input = input.replace(re, placeholder);
placeholders[placeholder] = word;
counter++;
});
input = input.replace(/([a-z0-9])([A-Z])/g, '$1 $2');
Object.entries(placeholders).forEach(([ph, word]) => {
input = input.replace(new RegExp(ph, 'g'), ` ${word} `);
});
let parts = input.split(' ');
const lastPart = parts.pop();
switch (lastPart) {
case "S":
parts.push('(seconds)');
break;
case "M":
parts.push('(minutes)');
break;
case "H":
parts.push('(hours)');
break;
case "Ms":
parts.push('(milliseconds)');
break;
default:
parts.push(lastPart);
break;
case 'S': parts.push('(seconds)'); break;
case 'M': parts.push('(minutes)'); break;
case 'H': parts.push('(hours)'); break;
case 'Ms': parts.push('(milliseconds)'); break;
default: parts.push(lastPart); break;
}
input = parts.join(' ');
return input.charAt(0).toUpperCase() + input.slice(1);
parts = parts.map(part => {
const match = reservedStrings.find(w => w.toUpperCase() === part.toUpperCase());
return match || part.charAt(0).toUpperCase() + part.slice(1);
});
return parts.join(' ').replace(/\s+/g, ' ').trim();
};
});