upstream: integrar Oasis 1.3.1
Base del merge a tres bandas: git 0.9.5 de epsylon, esta rama y el src de la
APK oficial 1.3.1 (la variante movil: OASIS_MOBILE, regex sin \p{}, audio y
video de Android). Corre en el mismo nodejs-mobile 18.20.4 que ya usabamos.
Se conserva de la rama: Karvan, identidades y multicuenta, topbar y barra
inferior, borrado de EXIF sin sharp, filtro hot del foro, RTC sin STUN y los
modulos apagados en movil (wallet, banking, torrents).
Se toma de upstream lo que ya hace de serie: respuesta citada en chats, ssb-lan
en movil, configuracion en ~/.ssb/oasis (sobrevive a reinstalar el backend).
El asistente de bienvenida deja elegir workflow tambien en movil.
This commit is contained in:
parent
8d838dd8b1
commit
c332afd6ea
265 changed files with 80970 additions and 29167 deletions
|
|
@ -5,9 +5,18 @@ const { getConfig } = require('../configs/config-manager.js');
|
|||
const { dedupeBy, norm } = require('../backend/dedupe');
|
||||
const { buildVoteTally } = require('../backend/vote_tally');
|
||||
const categories = require('../backend/opinion_categories');
|
||||
const { readTyped, memoIndex } = require('./typed_log');
|
||||
const logLimit = getConfig().ssbLogStream?.limit || 1000;
|
||||
const MIN_VOTE_DAYS = 7;
|
||||
|
||||
const INSTITUTIONAL_VOTE_TAG = /^(gov|govMethod|courtsCase|courtsMethod):/;
|
||||
const isVoteLocked = (v) => !!v && (
|
||||
(parseInt(v.totalVotes || 0, 10) || 0) > 0
|
||||
|| Object.values(v.opinions || {}).some(n => (Number(n) || 0) > 0)
|
||||
|| (Array.isArray(v.tags) && v.tags.some(t => INSTITUTIONAL_VOTE_TAG.test(String(t))))
|
||||
);
|
||||
const lockedError = () => Object.assign(new Error('Vote locked'), { code: 'VOTE_LOCKED' });
|
||||
|
||||
module.exports = ({ cooler }) => {
|
||||
let ssb;
|
||||
const openSsb = async () => {
|
||||
|
|
@ -17,13 +26,10 @@ module.exports = ({ cooler }) => {
|
|||
|
||||
const TYPE = 'votes';
|
||||
|
||||
const VOTES_TYPES = [TYPE, 'votesVote', 'votesOpinion', 'tombstone'];
|
||||
|
||||
async function getAllMessages(ssbClient) {
|
||||
return new Promise((resolve, reject) => {
|
||||
pull(
|
||||
ssbClient.createLogStream({ limit: logLimit }),
|
||||
pull.collect((err, results) => (err ? reject(err) : resolve(results)))
|
||||
);
|
||||
});
|
||||
return readTyped(ssbClient, VOTES_TYPES, { limit: logLimit });
|
||||
}
|
||||
|
||||
function buildIndex(messages) {
|
||||
|
|
@ -220,6 +226,7 @@ module.exports = ({ cooler }) => {
|
|||
ssbClient.get(tipId, (err, msg) => (err || !msg ? rej(new Error('Vote not found')) : res(msg)))
|
||||
);
|
||||
if (!vote.content || vote.content.createdBy !== userId) throw new Error('Not the author');
|
||||
if (isVoteLocked(vote.content) || isVoteLocked(await this.getVoteById(id).catch(() => null))) throw lockedError();
|
||||
const tombstone = {
|
||||
type: 'tombstone',
|
||||
target: tipId,
|
||||
|
|
@ -246,7 +253,7 @@ module.exports = ({ cooler }) => {
|
|||
if (c.createdBy !== userId) throw new Error('Not the author');
|
||||
const agg = await this.getVoteById(id);
|
||||
const aggTotalVotes = agg ? (parseInt(agg.totalVotes || 0, 10) || 0) : 0;
|
||||
if (agg && Object.keys(agg.opinions || {}).some(k => (agg.opinions[k] || 0) > 0)) throw new Error('Cannot edit vote after it has received opinions.');
|
||||
if (isVoteLocked(c) || isVoteLocked(agg)) throw lockedError();
|
||||
|
||||
let newDeadline = c.deadline;
|
||||
if (deadline != null && deadline !== '') {
|
||||
|
|
@ -324,7 +331,7 @@ module.exports = ({ cooler }) => {
|
|||
async getVoteById(id) {
|
||||
const ssbClient = await openSsb();
|
||||
const messages = await getAllMessages(ssbClient);
|
||||
const index = buildIndex(messages);
|
||||
const index = memoIndex('votes', messages, buildIndex);
|
||||
const activeList = computeActiveVotes(index);
|
||||
const byId = new Map(activeList.map(v => [v.id, v]));
|
||||
|
||||
|
|
@ -339,19 +346,7 @@ module.exports = ({ cooler }) => {
|
|||
return candidate;
|
||||
}
|
||||
|
||||
const msg = await new Promise((res, rej) =>
|
||||
ssbClient.get(id, (err, vote) => (err || !vote ? rej(new Error('Vote not found')) : res(vote)))
|
||||
);
|
||||
|
||||
const content = msg.content || {};
|
||||
const status = statusFromContent(content, moment());
|
||||
|
||||
return {
|
||||
id,
|
||||
latestId: id,
|
||||
...content,
|
||||
status
|
||||
};
|
||||
throw new Error('Vote not found');
|
||||
},
|
||||
|
||||
async listAll(filter = 'all') {
|
||||
|
|
@ -363,6 +358,8 @@ module.exports = ({ cooler }) => {
|
|||
|
||||
if (filter === 'mine') {
|
||||
list = list.filter(v => v.createdBy === userId);
|
||||
} else if (filter === 'recent') {
|
||||
list = list.filter(v => (Date.parse(v.createdAt || '') || 0) >= Date.now() - 86400000);
|
||||
} else if (filter === 'open') {
|
||||
list = list.filter(v => v.status === 'OPEN');
|
||||
} else if (filter === 'closed') {
|
||||
|
|
@ -389,4 +386,4 @@ module.exports = ({ cooler }) => {
|
|||
}
|
||||
};
|
||||
};
|
||||
|
||||
module.exports.isVoteLocked = isVoteLocked;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue