Skip to content

Commit

Permalink
6.4.0 (#1084)
Browse files Browse the repository at this point in the history
- Implement channel management
- Rewrite of complete group/channel management UI
- Implement group/channel destroy button
- Fix crash on message retraction
- Fix bug in Message Displayed Synchronization handling (XEP-0490)
- Improve AV-Call connectivity (allow incoming P2P connections)
- Implement optional DNSSEC validation
- Restructure settings menu to be more accessible and resemble the
structure of the new Conversations' settings menu
- Fix sharing files using share sheet
- Fix initial scroll position when opening a chat
- Add new setting to enable/disable in-app display of webpages in Safari
- Make more parts of the UI translatable (accessibility labels, section
headings etc.)
- Implement SVG support for received images and displaying avatars
- Fix typos in english strings
- Update license texts to include all used libraries
- Open websites linked in settings inline (but allow to open them in the
default browser, too)
  • Loading branch information
tmolitor-stud-tu committed Jun 17, 2024
2 parents 9199038 + 7d43529 commit 3a5baf1
Show file tree
Hide file tree
Showing 88 changed files with 3,082 additions and 1,769 deletions.
29 changes: 23 additions & 6 deletions .github/workflows/beta.build-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:
jobs:
# This workflow contains a single job called "build"
buildAndPublishBeta:
# The type of runner that the job will run on
name: "Build and Publish Beta Release"
runs-on: self-hosted
env:
APP_NAME: "Monal"
Expand Down Expand Up @@ -70,11 +70,6 @@ jobs:
run: ./scripts/uploadNonAlpha.sh beta
- name: Publish catalyst to appstore connect
run: xcrun altool --upload-app --file ./Monal/build/app/Monal.pkg --type macos --asc-provider S8D843U34Y -u "$(cat /Users/ci/apple_connect_upload_mail.txt)" -p "$(cat /Users/ci/apple_connect_upload_secret.txt)" --primary-bundle-id org.monal-im.prod.catalyst.monal
- name: Update translations
run: |
chmod +x ./scripts/updateLocalization.sh
chmod +x ./scripts/xliff_extractor.py
./scripts/updateLocalization.sh BUILDSERVER
- uses: actions/upload-artifact@v4
with:
name: monal-catalyst
Expand All @@ -95,3 +90,25 @@ jobs:
name: monal-ios-dsym
path: Monal/build/ios_Monal.xcarchive/dSYMs
if-no-files-found: error

updateTranslations:
name: Update Translations using Beta-Branch
runs-on: self-hosted
needs: [buildAndPublishBeta]
env:
APP_NAME: "Monal"
APP_DIR: "Monal.app"
BUILD_TYPE: "Beta"
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/checkout@v4
with:
clean: true
submodules: true
- name: Checkout submodules
run: git submodule update -f --init --remote
- name: Update translations
run: |
chmod +x ./scripts/updateLocalization.sh
chmod +x ./scripts/xliff_extractor.py
./scripts/updateLocalization.sh BUILDSERVER
2 changes: 2 additions & 0 deletions Monal/Alpha.Monal.macos.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.personal-information.location</key>
<true/>
<key>keychain-access-groups</key>
Expand Down
17 changes: 2 additions & 15 deletions Monal/Classes/AccountPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
// Copyright © 2023 monal-im.org. All rights reserved.
//

import SwiftUI
import monalxmpp

struct AccountPicker: View {
let delegate: SheetDismisserProtocol
let contacts: [MLContact]
Expand Down Expand Up @@ -43,25 +40,15 @@ struct AccountPicker: View {
.frame(maxWidth: .infinity)
.background(Color(UIColor.systemBackground))

let appDelegate = UIApplication.shared.delegate as! MonalAppDelegate
List {
ForEach(contacts) { contact in
if let accountEntry = DataLayer.sharedInstance().details(forAccount:contact.accountId) {
let accountJid = "\(accountEntry["username"] ?? "<unknown>" as NSString)@\(accountEntry["domain"] ?? "<unknown>" as NSString)"
let accountDisplayName = MLContact.ownDisplayName(forAccount:MLXMPPManager.sharedInstance().getConnectedAccount(forID: contact.accountId)!) as String
let accountContact = MLContact.createContact(fromJid:accountJid, andAccountNo:accountEntry["account_id"] as! NSNumber)
Button {
appDelegate.activeChats!.call(contact, with:callType)
(UIApplication.shared.delegate as! MonalAppDelegate).activeChats!.call(contact, with:callType)
} label: {
HStack(alignment: .center) {
Image(uiImage: MLImageManager.sharedInstance().getIconFor(accountContact)!)
.resizable()
.frame(width: 40, height: 40, alignment: .center)
VStack(alignment: .leading) {
Text(accountDisplayName)
Text(accountJid).font(.footnote).opacity(0.6)
}
}
ContactEntry(contact:ObservableKVOWrapper(accountContact), selfnotesPrefix:false)
}
}
}
Expand Down
1 change: 1 addition & 0 deletions Monal/Classes/ActiveChatsViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ NS_ASSUME_NONNULL_BEGIN
-(void) deleteConversation;
-(void) showSettings;
-(void) showPrivacySettings;
-(void) showNotificationSettings;
-(void) showDetails;
-(void) showRegisterWithUsername:(NSString*) username onHost:(NSString*) host withToken:(NSString* _Nullable) token usingCompletion:(monal_id_block_t _Nullable) callback;
-(void) showAddContactWithJid:(NSString*) jid preauthToken:(NSString* _Nullable) preauthToken prefillAccount:(xmpp* _Nullable) account andOmemoFingerprints:(NSDictionary* _Nullable) fingerprints;
Expand Down
10 changes: 8 additions & 2 deletions Monal/Classes/ActiveChatsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ -(void) showWarningsIfNeeded

if(![_mamWarningDisplayed containsObject:accountNo] && account.accountState >= kStateBound && account.connectionProperties.accountDiscoDone)
{
if(!account.connectionProperties.supportsMam2)
if(![account.connectionProperties.accountDiscoFeatures containsObject:@"urn:xmpp:mam:2"])
{
UIAlertController* messageAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:NSLocalizedString(@"Account %@", @""), account.connectionProperties.identity.jid] message:NSLocalizedString(@"Your server does not support MAM (XEP-0313). That means you could frequently miss incoming messages!! You should switch your server or talk to the server admin to enable this!", @"") preferredStyle:UIAlertControllerStyleAlert];
[messageAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Close", @"") style:UIAlertActionStyleCancel handler:^(UIAlertAction* action __unused) {
Expand Down Expand Up @@ -482,7 +482,7 @@ -(void) showWarningsIfNeeded

if(![_pushWarningDisplayed containsObject:accountNo] && account.accountState >= kStateBound && account.connectionProperties.accountDiscoDone)
{
if(!account.connectionProperties.supportsMam2)
if(![account.connectionProperties.accountDiscoFeatures containsObject:@"urn:xmpp:push:0"])
{
UIAlertController* messageAlert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:NSLocalizedString(@"Account %@", @""), account.connectionProperties.identity.jid] message:NSLocalizedString(@"Your server does not support PUSH (XEP-0357). That means you have to manually open the app to retrieve new incoming messages!! You should switch your server or talk to the server admin to enable this!", @"") preferredStyle:UIAlertControllerStyleAlert];
[messageAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Close", @"") style:UIAlertActionStyleCancel handler:^(UIAlertAction* action __unused) {
Expand All @@ -508,6 +508,12 @@ -(void) openConversationPlaceholder:(MLContact*) contact
}
}

-(void) showNotificationSettings
{
UIViewController* view = [[SwiftuiInterface new] makeViewWithName:@"ActiveChatsNotificatioSettings"];
[self presentViewController:view animated:YES completion:^{}];
}

-(void) showPrivacySettings
{
UIViewController* view = [[SwiftuiInterface new] makeViewWithName:@"ActiveChatsPrivacySettings"];
Expand Down
26 changes: 12 additions & 14 deletions Monal/Classes/AddContactMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import UniformTypeIdentifiers

struct AddContactMenu: View {
var delegate: SheetDismisserProtocol
static private let jidFaultyPattern = "^([^@]+@)?.+\\..{2,}$"
static private let jidFaultyPattern = "^([^@]+@)?.+(\\..{2,})?$"

@State private var connectedAccounts: [xmpp]
@State private var selectedAccount: Int
Expand Down Expand Up @@ -145,18 +145,16 @@ struct AddContactMenu: View {
trustFingerprints(self.importScannedFingerprints ? self.scannedFingerprints : [:], for:jid, on:account)
successAlert(title: Text("Permission Requested"), message: Text("The new contact will be added to your contacts list when the person you've added has approved your request."))
} else if type == "muc" {
showLoadingOverlay(overlay, headline: NSLocalizedString("Adding Group/Channel...", comment: ""))
account.mucProcessor.addUIHandler({data in
let success : Bool = (data as! NSDictionary)["success"] as! Bool;
performMucAction(account:account, mucJid:jid, overlay:overlay, headlineView:Text("Adding Group/Channel..."), descriptionView:Text("")) {
account.joinMuc(jid)
}.done { _ in
self.newContact = MLContact.createContact(fromJid: jid, andAccountNo: account.accountNo)
successAlert(title: Text("Success!"), message: Text("Successfully joined group/channel \(jid)!"))
}.catch { error in
errorAlert(title: Text("Error entering group/channel!"), message: Text("\(String(describing:error))"))
}.finally {
hideLoadingOverlay(overlay)
if success {
self.newContact = MLContact.createContact(fromJid: jid, andAccountNo: account.accountNo)
successAlert(title: Text("Success!"), message: Text(String.localizedStringWithFormat("Successfully joined group/channel %@!", jid)))
} else {
errorAlert(title: Text("Error entering group/channel!"), message: Text((data as! NSDictionary)["errorMessage"] as! String))
}
}, forMuc: jid)
account.joinMuc(jid)
}
} else {
hideLoadingOverlay(overlay)
errorAlert(title: Text("Error"), message: Text(errorMsg ?? "Undefined error"))
Expand Down Expand Up @@ -220,7 +218,7 @@ struct AddContactMenu: View {
if !showAlert {
let jidComponents = HelperTools.splitJid(toAdd)
if jidComponents["host"] == nil || jidComponents["host"]!.isEmpty {
errorAlert(title: Text("Error"), message: Text("Something went wrong while parsing the string..."))
errorAlert(title: Text("Error"), message: Text("Something went wrong while parsing your input..."))
showAlert = true
return
}
Expand Down Expand Up @@ -287,7 +285,7 @@ struct AddContactMenu: View {
}
}
.addLoadingOverlay(overlay)
.navigationBarTitle("Add Contact or Channel", displayMode: .inline)
.navigationBarTitle(Text("Add Contact or Channel"), displayMode: .inline)
.navigationViewStyle(.stack)
.toolbar(content: {
ToolbarItemGroup(placement: .navigationBarTrailing) {
Expand Down
52 changes: 29 additions & 23 deletions Monal/Classes/BackgroundSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@
// BackgroundSettings.swift
// Monal
//
// Created by admin on 14.11.22.
// Created by Thilo Molitor on 14.11.22.
// Copyright © 2022 monal-im.org. All rights reserved.
//

import SwiftUI
import UniformTypeIdentifiers
import monalxmpp

@ViewBuilder
func title(contact: ObservableKVOWrapper<MLContact>?) -> some View {
if let contact = contact {
Expand All @@ -27,20 +23,19 @@ struct BackgroundSettings: View {
@State private var showingImagePicker = false
@State private var inputImage: UIImage?
let contact: ObservableKVOWrapper<MLContact>?
let delegate: SheetDismisserProtocol

init(contact: ObservableKVOWrapper<MLContact>?, delegate: SheetDismisserProtocol) {
init(contact: ObservableKVOWrapper<MLContact>?) {
self.contact = contact
self.delegate = delegate
_inputImage = State(initialValue:MLImageManager.sharedInstance().getBackgroundFor(self.contact?.obj))

}

var body: some View {
VStack {
Form {
Group {
Section(header:title(contact:contact)) {
Section(header:title(contact:contact)) {
VStack(spacing: 20) {
Spacer().frame(height: 0)
Button(action: {
#if targetEnvironment(macCatalyst)
let picker = DocumentPickerViewController(
Expand All @@ -62,32 +57,44 @@ struct BackgroundSettings: View {
#endif
}) {
if let inputImage = inputImage {
ZStack(alignment: .topLeading) {
HStack(alignment: .center) {
Image(uiImage:inputImage)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: .infinity, alignment: .center)
}
HStack(alignment: .center) {
Image(uiImage:inputImage)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: .infinity, alignment: .center)
}
.addTopRight {
Button(action: {
self.inputImage = nil
}, label: {
Image(systemName: "xmark.circle.fill").foregroundColor(.red)
Image(systemName: "xmark.circle.fill")
.resizable()
.frame(width: 32.0, height: 32.0)
.accessibilityLabel(Text("Remove Background Image"))
.applyClosure { view in
if #available(iOS 15, *) {
view
.symbolRenderingMode(.palette)
.foregroundStyle(.white, .red)
} else {
view.foregroundColor(.red)
}
}
})
.buttonStyle(.borderless)
.offset(x: -7, y: -7)
.offset(x: 12, y: -12)
}
.frame(maxWidth: .infinity, alignment: .center)
} else {
Text("Select background image")
.frame(maxWidth: .infinity, alignment: .center)
}
}
.accessibilityLabel(Text("Change Background Image"))
.sheet(isPresented:$showingImagePicker) {
ImagePicker(image:$inputImage)
}

//>= ios16
//>= ios 16
/*
PhotosPicker(selection:$selectedItem, matching:.images, photoLibrary:.shared()) {
if let inputImage = inputImage {
Expand Down Expand Up @@ -133,8 +140,7 @@ struct BackgroundSettings: View {
}

struct BackgroundSettings_Previews: PreviewProvider {
static var delegate = SheetDismisserProtocol()
static var previews: some View {
BackgroundSettings(contact:nil, delegate:delegate)
BackgroundSettings(contact:nil)
}
}
Loading

0 comments on commit 3a5baf1

Please sign in to comment.