Compare commits

...

4 Commits

16 changed files with 113 additions and 41 deletions

View File

@ -291,7 +291,9 @@
"cannotEnableRedirectSubtext": "You must first set a proxy service to redirect to. To do so, tap the field next to the switch.",
"urlEmpty": "URL cannot be empty",
"urlInvalid": "Invalid URL",
"redirectDialogTitle": "$serviceName Redirect"
"redirectDialogTitle": "$serviceName Redirect",
"stickersPrivacy": "Keep sticker list public",
"stickersPrivacySubtext": "If enabled, everyone will be able to see your list of installed sticker packs."
},
"stickers": {
"title": "Stickers",

View File

@ -291,7 +291,9 @@
"cannotEnableRedirectSubtext": "Du must zuerst einen Proxydienst auswählen. Dazu berühre das Feld neben dem Schalter.",
"urlEmpty": "URL kann nicht leer sein",
"urlInvalid": "Ungültige URL",
"redirectDialogTitle": "${serviceName}weiterleitung"
"redirectDialogTitle": "${serviceName}weiterleitung",
"stickersPrivacy": "Stickerliste öffentlich halten",
"stickersPrivacySubtext": "Wenn eingeschaltet, dann kann jeder die Liste Deiner installierten Stickerpacks sehen."
},
"stickers": {
"title": "Stickers",

View File

@ -46,42 +46,27 @@ class AvatarService {
final cs = GetIt.I.get<ConversationService>();
final rs = GetIt.I.get<RosterService>();
final originalConversation = await cs.getConversationByJid(jid);
var saved = false;
final originalRoster = await rs.getRosterItemByJid(jid);
// Clean the raw data. Since this may arrive by chunks, those chunks may contain
// weird data pieces.
if (originalConversation == null && originalRoster == null) return;
final avatarPath = await saveAvatarInCache(
data,
hash,
jid,
(originalConversation?.avatarUrl ?? originalRoster?.avatarUrl)!,
);
if (originalConversation != null) {
final avatarPath = await saveAvatarInCache(
data,
hash,
jid,
originalConversation.avatarUrl,
);
saved = true;
final conv = await cs.updateConversation(
originalConversation.id,
avatarUrl: avatarPath,
);
sendEvent(ConversationUpdatedEvent(conversation: conv));
} else {
_log.warning('Failed to get conversation');
}
final originalRoster = await rs.getRosterItemByJid(jid);
if (originalRoster != null) {
var avatarPath = '';
if (saved) {
avatarPath = await getAvatarPath(jid, hash);
} else {
avatarPath = await saveAvatarInCache(
data,
hash,
jid,
originalRoster.avatarUrl,
);
}
final roster = await rs.updateRosterItem(
originalRoster.id,
avatarUrl: avatarPath,

View File

@ -419,4 +419,12 @@ Future<void> createDatabase(Database db, int version) async {
'false',
).toDatabaseJson(),
);
await db.insert(
preferenceTable,
Preference(
'isStickersNodePublic',
typeBool,
'true',
).toDatabaseJson(),
);
}

View File

@ -30,6 +30,7 @@ import 'package:moxxyv2/service/database/migrations/0000_stickers_hash_key2.dart
import 'package:moxxyv2/service/database/migrations/0000_stickers_missing_attributes.dart';
import 'package:moxxyv2/service/database/migrations/0000_stickers_missing_attributes2.dart';
import 'package:moxxyv2/service/database/migrations/0000_stickers_missing_attributes3.dart';
import 'package:moxxyv2/service/database/migrations/0000_stickers_privacy.dart';
import 'package:moxxyv2/service/database/migrations/0000_xmpp_state.dart';
import 'package:moxxyv2/service/helpers.dart';
import 'package:moxxyv2/service/not_specified.dart';
@ -81,7 +82,7 @@ class DatabaseService {
_db = await openDatabase(
dbPath,
password: key,
version: 24,
version: 25,
onCreate: createDatabase,
onConfigure: (db) async {
// In order to do schema changes during database upgrades, we disable foreign
@ -186,6 +187,10 @@ class DatabaseService {
_log.finest('Running migration for database version 24');
await upgradeFromV23ToV24(db);
}
if (oldVersion < 25) {
_log.finest('Running migration for database version 25');
await upgradeFromV24ToV25(db);
}
},
);

View File

@ -0,0 +1,14 @@
import 'package:moxxyv2/service/database/constants.dart';
import 'package:moxxyv2/shared/models/preference.dart';
import 'package:sqflite_sqlcipher/sqflite.dart';
Future<void> upgradeFromV24ToV25(Database db) async {
await db.insert(
preferenceTable,
Preference(
'isStickersNodePublic',
typeBool,
'true',
).toDatabaseJson(),
);
}

View File

@ -348,6 +348,37 @@ Future<void> performSetPreferences(SetPreferencesCommand command, { dynamic extr
css.disableDatabaseListener();
}
}
// TODO(Unknown): Maybe handle this in StickersService
// If sticker visibility was changed, apply the settings to the PubSub node
final pm = GetIt.I.get<XmppConnection>()
.getManagerById<PubSubManager>(pubsubManager)!;
final ownJid = (await GetIt.I.get<XmppService>().getXmppState()).jid!;
if (command.preferences.isStickersNodePublic && !oldPrefs.isStickersNodePublic) {
// Set to open
unawaited(
pm.configure(
ownJid,
stickersXmlns,
const PubSubPublishOptions(
accessModel: 'open',
maxItems: 'max',
),
),
);
} else if (!command.preferences.isStickersNodePublic && oldPrefs.isStickersNodePublic) {
// Set to presence
unawaited(
pm.configure(
ownJid,
stickersXmlns,
const PubSubPublishOptions(
accessModel: 'presence',
maxItems: 'max',
),
),
);
}
// Set the locale
final locale = command.preferences.languageLocaleCode == 'default' ?

View File

@ -397,6 +397,7 @@ class OmemoService {
for (final deviceId in _fingerprintCache[bareJid]!.keys) {
if (deviceId == ownId) continue;
if (keys.indexWhere((key) => key.deviceId == deviceId) != -1) continue;
final fingerprint = _fingerprintCache[bareJid]![deviceId]!;
keys.add(

View File

@ -10,6 +10,7 @@ import 'package:moxxmpp/moxxmpp.dart' as moxxmpp;
import 'package:moxxyv2/service/database/database.dart';
import 'package:moxxyv2/service/helpers.dart';
import 'package:moxxyv2/service/httpfiletransfer/helpers.dart';
import 'package:moxxyv2/service/preferences.dart';
import 'package:moxxyv2/service/service.dart';
import 'package:moxxyv2/service/xmpp.dart';
import 'package:moxxyv2/shared/events.dart';
@ -89,10 +90,17 @@ class StickersService {
}
Future<void> _publishStickerPack(moxxmpp.StickerPack pack) async {
final prefs = await GetIt.I.get<PreferencesService>().getPreferences();
final state = await GetIt.I.get<XmppService>().getXmppState();
final result = await GetIt.I.get<moxxmpp.XmppConnection>()
.getManagerById<moxxmpp.StickersManager>(moxxmpp.stickersManager)!
.publishStickerPack(moxxmpp.JID.fromString(state.jid!), pack);
.publishStickerPack(
moxxmpp.JID.fromString(state.jid!),
pack,
accessModel: prefs.isStickersNodePublic ?
'open' :
null,
);
if (result.isType<moxxmpp.PubSubError>()) {
_log.severe('Failed to publish sticker pack');

View File

@ -1,5 +1,4 @@
import 'dart:io';
import 'package:path/path.dart' as pathlib;
import 'package:path_provider/path_provider.dart';

View File

@ -31,6 +31,7 @@ class PreferencesState with _$PreferencesState {
@Default(false) bool enableContactIntegration,
@Default(true) bool enableStickers,
@Default(true) bool autoDownloadStickersFromContacts,
@Default(true) bool isStickersNodePublic,
}) = _PreferencesState;
// JSON serialization

View File

@ -22,6 +22,7 @@ const Color bubbleColorSentQuoted = bubbleColorSent;
const Color bubbleColorReceived = Color(0xff222222);
const Color bubbleColorReceivedQuoted = bubbleColorReceived;
const Color bubbleColorUnencrypted = Color(0xffd40000);
const Color bubbleColorNewDevice = Color(0xffeee8d5);
const Color settingsSectionTitleColor = Color(0xffb72fe7);

View File

@ -70,6 +70,20 @@ class PrivacyPage extends StatelessWidget {
},
),
),
SettingsRow(
title: t.pages.settings.privacy.stickersPrivacy,
description: t.pages.settings.privacy.stickersPrivacySubtext,
suffix: Switch(
value: state.isStickersNodePublic,
onChanged: (value) {
context.read<PreferencesBloc>().add(
PreferencesChangedEvent(
state.copyWith(isStickersNodePublic: value),
),
);
},
),
),
SectionTitle(t.pages.settings.privacy.conversationsSection),
SettingsRow(

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:moxxyv2/i18n/strings.g.dart';
import 'package:moxxyv2/ui/bloc/devices_bloc.dart';
import 'package:moxxyv2/ui/constants.dart';
class NewDeviceBubble extends StatelessWidget {
const NewDeviceBubble({
@ -18,14 +19,14 @@ class NewDeviceBubble extends StatelessWidget {
padding: const EdgeInsets.all(8),
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(12)),
child: InkWell(
onTap: () {
context.read<DevicesBloc>().add(
DevicesRequestedEvent(data['jid']! as String),
);
},
child: ColoredBox(
color: const Color(0xffeee8d5),
child: Material(
color: bubbleColorNewDevice,
child: InkWell(
onTap: () {
context.read<DevicesBloc>().add(
DevicesRequestedEvent(data['jid']! as String),
);
},
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8,

View File

@ -836,7 +836,7 @@ packages:
description:
path: "packages/moxxmpp"
ref: HEAD
resolved-ref: "62001c1e29b644fcf7fe12618d77571853fd073e"
resolved-ref: "55d2ef9c25d383806bc780597a96d3c2887a4aa1"
url: "https://git.polynom.me/Moxxy/moxxmpp.git"
source: git
version: "0.1.6+1"

View File

@ -140,7 +140,7 @@ dependency_overrides:
moxxmpp:
git:
url: https://git.polynom.me/Moxxy/moxxmpp.git
rev: 596693c2067bc3fe73250f07cd88e7040a285537
rev: 55d2ef9c25d383806bc780597a96d3c2887a4aa1
path: packages/moxxmpp
extra_licenses: