integrar la 1.3.5 del dev y perfiles Minimo, Acampada y Activista

Lo del dev, tal cual desde el nodejs-project de su APK oficial 1.3.5, mezclado
a tres bandas con la 1.3.3 como base. Lo que no habiamos tocado se coge entero.

Conflictos:
- backend.js: su middleware nuevo de media va delante de nuestro router.
- main_views.js y bookmark_view.js: lo suyo. Su menu de tarjeta (⋯) ya aparta
  borrar del pulgar, que era lo que hacia nuestro cambio.
- settings_view.js y tribes_view.js: lo suyo mas nuestra linea de enganche.

La 1.3.5 trae una cabecera de modulo para el movil (apkModbar) que se lleva la
primera caja de fichas, el buscador y los contadores. Con el skin Activista su
CSS (OasisMobile.css) no se carga: se le da estilo en mobile_ux.css, los avisos
suben encima con order y se ajusta la cabecera nueva de las tarjetas. Filtrar
va ahora dentro de la caja de fichas (casilla + etiqueta) para viajar con ella.

Perfiles: Minimo (6 modulos, de serie), Acampada (16), Activista (24, con
tribus, votaciones, campañas, encuestas y tareas) y despues los del dev por
numero de modulos.
This commit is contained in:
hacklab 2026-10-22 12:12:20 +02:00
parent ff91ef938c
commit 83f26ba19e
157 changed files with 6633 additions and 4710 deletions

View file

@ -3,6 +3,7 @@ const { getConfig } = require('../configs/config-manager.js');
const { buildValidatedTombstoneSet } = require('./tombstone_validator');
const { readTyped, memoIndex } = require('./typed_log');
const { versionGroups } = require('../backend/dedupe');
const opinionRules = require('../backend/opinion_categories');
const logLimit = getConfig().ssbLogStream?.limit || 1000;
@ -35,7 +36,7 @@ const normalizeTags = (raw) => {
return list.map(t => clean(t)).filter(Boolean).slice(0, 20);
};
module.exports = ({ cooler, isPublic = false, tribeCrypto = null, chatsModel = null }) => {
module.exports = ({ cooler, isPublic = false, cryptoModel = null, chatsModel = null }) => {
let ssb;
const openSsb = async () => { if (!ssb) ssb = await cooler.open(); return ssb; };
@ -44,10 +45,10 @@ module.exports = ({ cooler, isPublic = false, tribeCrypto = null, chatsModel = n
const getAllMessages = async (ssbClient) => readTyped(ssbClient, POLLS_TYPES, { limit: logLimit });
const decryptField = (value, keys) => {
if (!tribeCrypto || typeof value !== 'string' || !value) return null;
if (!cryptoModel || typeof value !== 'string' || !value) return null;
for (const k of keys) {
try {
const out = tribeCrypto.decryptWithKey(value, k);
const out = cryptoModel.decryptWithKey(value, k);
if (typeof out === 'string' && out) return out;
} catch (_) {}
}
@ -312,9 +313,9 @@ module.exports = ({ cooler, isPublic = false, tribeCrypto = null, chatsModel = n
...(data.houseKey ? { houseKey: String(data.houseKey) } : {})
};
const key = await scopeKey({ chatId: data.chatId, tribeId: data.tribeId });
if (key && tribeCrypto) {
content.encryptedQuestion = tribeCrypto.encryptWithKey(question, key);
content.encryptedOptions = tribeCrypto.encryptWithKey(JSON.stringify(options), key);
if (key && cryptoModel) {
content.encryptedQuestion = cryptoModel.encryptWithKey(question, key);
content.encryptedOptions = cryptoModel.encryptWithKey(JSON.stringify(options), key);
} else {
content.question = question;
content.options = options;
@ -338,6 +339,7 @@ module.exports = ({ cooler, isPublic = false, tribeCrypto = null, chatsModel = n
if (!Number.isFinite(t)) throw new Error('Invalid deadline');
}
const question = data.question !== undefined ? clean(data.question) : poll.question;
opinionRules.assertMediaKept(poll, question !== poll.question || JSON.stringify(options) !== JSON.stringify(poll.options));
const content = {
type: POLL_TYPE,
replaces: poll.tipId,
@ -356,9 +358,9 @@ module.exports = ({ cooler, isPublic = false, tribeCrypto = null, chatsModel = n
...(poll.houseKey ? { houseKey: poll.houseKey } : {})
};
const key = await scopeKey({ chatId: poll.chatId, tribeId: poll.tribeId });
if (key && tribeCrypto) {
content.encryptedQuestion = tribeCrypto.encryptWithKey(question, key);
content.encryptedOptions = tribeCrypto.encryptWithKey(JSON.stringify(options), key);
if (key && cryptoModel) {
content.encryptedQuestion = cryptoModel.encryptWithKey(question, key);
content.encryptedOptions = cryptoModel.encryptWithKey(JSON.stringify(options), key);
} else {
content.question = question;
content.options = options;
@ -386,7 +388,7 @@ module.exports = ({ cooler, isPublic = false, tribeCrypto = null, chatsModel = n
...(poll.chatId ? { chatId: poll.chatId } : {})
};
const key = await scopeKey({ chatId: poll.chatId, tribeId: poll.tribeId });
if (key && tribeCrypto) content.encryptedChoices = tribeCrypto.encryptWithKey(JSON.stringify(unique), key);
if (key && cryptoModel) content.encryptedChoices = cryptoModel.encryptWithKey(JSON.stringify(unique), key);
else content.choices = unique;
return new Promise((res, rej) => ssbClient.publish(content, (err, msg) => err ? rej(err) : res(msg)));
},