...
 
Commits (86)
......@@ -13,7 +13,7 @@ IF("${RING_VERSION}" STREQUAL "")
ENDIF("${RING_VERSION}" STREQUAL "")
# if build for App Store version and build number should be incremented
IF("${RELEASE_TYPE}" STREQUAL "AppStore")
SET(RING_VERSION_NAME "1.35")
SET(RING_VERSION_NAME "1.51")
ELSE()
SET(RING_VERSION_NAME "1")
ENDIF()
......@@ -37,6 +37,8 @@ FIND_PACKAGE(OpenGL REQUIRED)
EXECUTE_PROCESS(COMMAND git submodule update --init
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
get_filename_component(PARENT_DIR ${CMAKE_SOURCE_DIR} PATH)
INCLUDE(ExternalProject)
ExternalProject_Add(libqrencode
GIT_SUBMODULES libqrencode
......@@ -52,6 +54,17 @@ ExternalProject_Add(libqrencode
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/libqrencode/include)
LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/libqrencode/lib)
INCLUDE_DIRECTORIES(${PARENT_DIR}/daemon/contrib/native/ffmpeg)
set(SHADERS_FILE "Shader.metallib")
add_custom_command (OUTPUT ${CMAKE_SOURCE_DIR}/Shader.metallib
COMMAND ${CMAKE_SOURCE_DIR}/generateShaderLib.sh
COMMENT "Creating Shader.metallib")
add_custom_target(
shader ALL
DEPENDS ${CMAKE_SOURCE_DIR}/Shader.metallib
)
IF(NOT (${ENABLE_SPARKLE} MATCHES false))
MESSAGE("Sparkle auto-update enabled")
......@@ -101,8 +114,6 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w")
#Files to compile
SET(ringclient_CONTROLLERS
src/QNSTreeController.mm
src/QNSTreeController.h
src/CurrentCallVC.mm
src/CurrentCallVC.h
src/GeneralPrefsVC.mm
......@@ -124,8 +135,6 @@ SET(ringclient_CONTROLLERS
src/AccAdvancedRingVC.h
src/CertificateWC.mm
src/CertificateWC.h
src/RestoreAccountWC.mm
src/RestoreAccountWC.h
src/AudioPrefsVC.mm
src/AudioPrefsVC.h
src/VideoPrefsVC.mm
......@@ -167,12 +176,18 @@ SET(ringclient_CONTROLLERS
src/AccountSettingsVC.h
src/LeaveMessageVC.mm
src/LeaveMessageVC.h
src/RecordFileVC.mm
src/RecordFileVC.h
src/ChooseContactVC.mm
src/ChooseContactVC.h
src/CallInConferenceVC.mm
src/CallInConferenceVC.h
src/ConnectToAccManagerVC.mm
src/ConnectToAccManagerVC.h
src/AccountBackupVC.mm
src/AccountBackupVC.h
)
SET(ringclient_BACKENDS
src/backends/AddressBookBackend.mm
src/backends/AddressBookBackend.h)
SET(ringclient_VIEWS
src/views/CallView.mm
src/views/CallView.h
......@@ -212,6 +227,12 @@ SET(ringclient_VIEWS
src/views/HoverButton.mm
src/views/CenteredClipView.h
src/views/CenteredClipView.mm
src/views/CallMTKView.h
src/views/CallMTKView.mm
src/views/GradientView.h
src/views/GradientView.mm
src/views/MovableView.h
src/views/MovableView.mm
)
SET(ringclient_OTHERS
......@@ -219,6 +240,8 @@ SET(ringclient_OTHERS
src/AppDelegate.mm
src/AppDelegate.h
src/Constants.h
src/VideoCommon.h
src/VideoCommon.mm
src/INDSequentialTextSelectionManager.mm
src/INDSequentialTextSelectionManager.h
src/delegates/ImageManipulationDelegate.mm
......@@ -229,8 +252,9 @@ SET(ringclient_OTHERS
src/NSString+Extensions.h
src/NSString+Extensions.mm
src/RingMainWindow.h
src/RingMainWindow.mm)
src/RingMainWindow.mm
src/Shader.metal
)
SET(ringclient_XIBS
MainMenu
......@@ -246,7 +270,6 @@ SET(ringclient_XIBS
PreferencesWindow
RingWizard
CertificateWindow
RestoreAccountWindow
ExportPasswordWindow
MigrateRingAccountsWindow
Conversation
......@@ -261,6 +284,11 @@ SET(ringclient_XIBS
AddSIPAccountVC
AccountSettings
LeaveMessageVC
RecordFileVC
ChooseContactVC
CallInConferenceVC
ConnectToAccManagerVC
AccountBackupVC
)
# Icons
......@@ -317,12 +345,17 @@ ${CMAKE_CURRENT_SOURCE_DIR}/data/dark/qrcode.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_action_video.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/pending_contact_request.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_file_upload.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_record_stop.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_camera.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_audio_msg.png
${CMAKE_CURRENT_SOURCE_DIR}/data/light/ic_picture.png)
SET_SOURCE_FILES_PROPERTIES(${ring_ICONS} PROPERTIES
MACOSX_PACKAGE_LOCATION Resources)
SET_SOURCE_FILES_PROPERTIES(Credits.rtf PROPERTIES
MACOSX_PACKAGE_LOCATION Resources)
SET_SOURCE_FILES_PROPERTIES(Shader.metallib PROPERTIES
MACOSX_PACKAGE_LOCATION Resources)
# package ringtones
IF(NOT IS_DIRECTORY ${RINGTONE_DIR})
......@@ -398,13 +431,13 @@ ENDFOREACH()
SET(TO_ADD
${ringclient_CONTROLLERS}
${ringclient_BACKENDS}
${ringclient_VIEWS}
${ringclient_OTHERS}
${ringclient_XIBS_FOR_EXECUTABLE}
${LOCALIZABLE_FILES}
${myApp_ICON}
Credits.rtf
Shader.metallib
${ring_ICONS}
${ring_RINGTONES})
......@@ -438,6 +471,8 @@ TARGET_LINK_LIBRARIES( ${PROJ_NAME}
-lqrencode
)
target_link_libraries(${PROJ_NAME} ${PARENT_DIR}/daemon/contrib/x86_64-apple-darwin${CMAKE_SYSTEM_VERSION}/lib/libavutil.a)
IF(ENABLE_SPARKLE)
TARGET_LINK_LIBRARIES(${PROJ_NAME} ${SPARKLE_FRAMEWORK})
ENDIF(ENABLE_SPARKLE)
......@@ -448,6 +483,8 @@ SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Quartz")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework AVFoundation")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework AddressBook")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework SystemConfiguration")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework MetalKit")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Metal")
# These variables are specific to our plist and are NOT standard CMake variables
SET(MACOSX_BUNDLE_NSMAIN_NIB_FILE "MainMenu")
......@@ -471,6 +508,7 @@ ELSE()
SET_TARGET_PROPERTIES(${PROJ_NAME} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/cmake/MacOSXBundleInfo.plist.in
MACOSX_BUNDLE_GUI_IDENTIFIER "cx.ring"
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_LIST_DIR}/data/HardenedRuntimeEntitlements/Jami.entitlements"
MACOSX_BUNDLE_SHORT_VERSION_STRING "${RING_VERSION_NAME}"
MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJ_NAME} ${RING_VERSION_NAME}"
MACOSX_BUNDLE_BUNDLE_VERSION ${RING_VERSION}
......@@ -478,8 +516,10 @@ ELSE()
MACOSX_BUNDLE_INFO_STRING "Build of ${PROJ_NAME}, version ${RING_VERSION}"
MACOSX_BUNDLE_BUNDLE_NAME ${PROJ_NAME}
MACOSX_BUNDLE_ICON_FILE "appicon.icns"
XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME TRUE
)
ENDIF()
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym")
# Make sure we can find the 'ibtool' program. If we can NOT find it we
# skip generation of this project
FIND_PROGRAM(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin")
......
......@@ -9,11 +9,11 @@
\f0\i\fs24 \cf0 \
\fs28 "
\f1\b Live Free or Die"
\f1\b Free as in Freedom"
\f0\b0\fs24 \
\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc\partightenfactor0
{\field{\*\fldinst{HYPERLINK "https://ring.cx/"}}{\fldrslt \cf0 jami.net}}\
{\field{\*\fldinst{HYPERLINK "https://jami.net/"}}{\fldrslt \cf0 jami.net}}\
\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc\partightenfactor0
......@@ -62,5 +62,5 @@ Based on SFLphone's project\
\f2\i0\b Translated by
\f0\i\b0 \
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc\partightenfactor0
{\field{\*\fldinst{HYPERLINK "https://www.transifex.com/savoirfairelinux/ring/"}}{\fldrslt \cf0 https://www.transifex.com/savoirfairelinux/ring/}}\
}
\ No newline at end of file
{\field{\*\fldinst{HYPERLINK "https://www.transifex.com/savoirfairelinux/jami/"}}{\fldrslt \cf0 https://www.transifex.com/savoirfairelinux/jami/}}\
}
Ring Mac OSX
Jami for macOS
**********
This is the official Mac port of Ring.
This is the official Mac port of Jami.
For more information about the ring project, see the following:
- Main website: https://ring.cx/
- Bug tracker: https://tuleap.ring.cx/projects/ring/
- Repositories: https://gerrit-ring.savoirfairelinux.com
- Main website: https://jami.net/
- Bug tracker: https://git.jami.net
- Repositories: https://review.jami.net
| App | CI | Packaging
| :-: | :-: | :-:
| [![Download from ring.cx](https://img.shields.io/badge/download-cx.ring-blue.svg)](https://ring.cx/en/download/mac-osx) | [![Build Status](https://test.savoirfairelinux.com/buildStatus/icon?job=ring-client-macosx)](https://test.savoirfairelinux.com/job/ring-client-macosx/) | [![Build Status](https://test.savoirfairelinux.com/buildStatus/icon?job=ring-packaging-client-macosx)](https://test.savoirfairelinux.com/job/ring-packaging-client-macosx/)
| [![Download from jami.net](https://img.shields.io/badge/download-cx.ring-blue.svg)](https://jami.net/download-jami-macos) | [![Build Status](https://test.savoirfairelinux.com/buildStatus/icon?job=ring-client-macosx)](https://test.savoirfairelinux.com/job/ring-client-macosx/) | [![Build Status](https://test.savoirfairelinux.com/buildStatus/icon?job=ring-packaging-client-macosx)](https://test.savoirfairelinux.com/job/ring-packaging-client-macosx/)
Requirements
=============
- Ring daemon
- Jami daemon
- libRingClient (Qt5 version)
- Qt5 Core
- Cocoa framework
......@@ -25,7 +25,7 @@ Build instructions
Build Sparkle framework (optional)
----------------------------------
Ring can ship with the Sparkle framework to allow automatic app updates.
Jami can ship with the Sparkle framework to allow automatic app updates.
This can be disabled for your custom build by specifying -DENABLE_SPARKLE=false
in the cmake phase.
......
......@@ -15,7 +15,7 @@
<key>SUPublicDSAKeyFile</key>
<string>dsa_pub.pem</string>
<key>SUFeedURL</key>
<string>https://dl.ring.cx/mac_osx/sparkle-ring.xml</string>
<string>https://dl.jami.net/mac_osx/sparkle-ring.xml</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.personal-information.photos-library</key>
<true/>
</dict>
</plist>
data/dark/ic_action_chat.png

248 Bytes | W: | H:

data/dark/ic_action_chat.png

184 Bytes | W: | H:

data/dark/ic_action_chat.png
data/dark/ic_action_chat.png
data/dark/ic_action_chat.png
data/dark/ic_action_chat.png
  • 2-up
  • Swipe
  • Onion skin
data/dark/ic_action_record.png

2.82 KB | W: | H:

data/dark/ic_action_record.png

234 Bytes | W: | H:

data/dark/ic_action_record.png
data/dark/ic_action_record.png
data/dark/ic_action_record.png
data/dark/ic_action_record.png
  • 2-up
  • Swipe
  • Onion skin
data/dark/ic_audio_file.png

756 Bytes | W: | H:

data/dark/ic_audio_file.png

1.11 KB | W: | H:

data/dark/ic_audio_file.png
data/dark/ic_audio_file.png
data/dark/ic_audio_file.png
data/dark/ic_audio_file.png
  • 2-up
  • Swipe
  • Onion skin
xcrun -sdk macosx metal -c ../src/Shader.metal -o ../Shader.air
xcrun -sdk macosx metallib ../Shader.air -o ../Shader.metallib
#!/bin/bash
echo ""
cd build-local
/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool --notarize-app -t osx -f Jami.app.zip --primary-bundle-id ${BUNDLE_ID} -u ${APPLE_ACCOUNT} -p ${APPLE_PASSWORD} --output-format xml -itc_provider ${TEAM_ID} > UploadInfo.plist
REQUESTID=$(xmllint --xpath "/plist/dict[key='notarization-upload']/dict/key[.='RequestUUID']/following-sibling::string[1]/node()" UploadInfo.plist)
echo "file uploaded for notarization"
echo ${REQUESTID}
sleep 60
x=1
while [ $x -le 15 ];
do
/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/altool --notarization-info ${REQUESTID} -u ${APPLE_ACCOUNT} -p ${APPLE_PASSWORD} --output-format xml > RequestedInfo.plist
ANSWER=$(xmllint --xpath "/plist/dict[key='notarization-info']/dict/key[.='Status']/following-sibling::string[1]/node()" RequestedInfo.plist)
if [ "$ANSWER" == "in progress" ];
then
echo "notarization in progress"
sleep 60
x=$(( $x + 1 ))
elif [ "$ANSWER" == "success" ]
then
echo "notarization success"
break
else
echo "notarization failed"
break
exit 1
fi
done
ANSWER=$(xmllint --xpath "/plist/dict[key='notarization-info']/dict/key[.='Status']/following-sibling::string[1]/node()" RequestedInfo.plist)
if [ "$ANSWER" != "success" ];
then
echo "notarization failed"
exit 1
fi
......@@ -14,7 +14,7 @@ security import certificates/certificates/distribution/Certificates.p12 -k $KEYC
DELIVER_PASSWORD=$APPLE_PASSWORD fastlane sigh --app_identifier $BUNDLE_ID --username $APPLE_ACCOUNT --readonly true --platform macos --team_id $TEAM_ID
security set-key-partition-list -S apple-tool:,apple:,productbuild: -s -k $KEYCHAIN_PASSWORD $KEYCHAIN_NAME > /dev/null 2>&1
echo "start signing"
macdeployqt ./Jami.app -codesign="${APP_CERTIFICATE}"
macdeployqt ./Jami.app -no-strip -codesign="${APP_CERTIFICATE}"
codesign --force --sign "${APP_CERTIFICATE}" --entitlements ../data/Jami.entitlements Jami.app
codesign --verify Jami.app
echo "create .pkg"
......
......@@ -52,7 +52,7 @@ const NSInteger BOOTSTRAP_SERVER_TAG = 300;
-(void) viewDidLoad {
[super viewDidLoad];
[[self view] setAutoresizingMask: NSViewMinXMargin | NSViewMaxXMargin];
[[self view] setAutoresizingMask: NSViewMinXMargin | NSViewMaxXMargin | NSViewWidthSizable];
[self updateView];
}
......
......@@ -24,7 +24,7 @@
#import <api/newaccountmodel.h>
#import <api/newdevicemodel.h>
#import <api/newcodecmodel.h>
#import <account.h>
#import <api/account.h>
@interface AccAdvancedVC ()
......
......@@ -42,17 +42,21 @@
#import "views/RoundedTextField.h"
#import "ExportPasswordWC.h"
#import "utils.h"
#import "Constants.h"
@interface AccRingGeneralVC ()
@property (unsafe_unretained) IBOutlet NSTextField *displayNameField;
@property (unsafe_unretained) IBOutlet NSTextField *ringIDField;
@property (unsafe_unretained) IBOutlet NSTextField *registeredNameField;
@property (unsafe_unretained) IBOutlet NSTextField *passwordField;
@property (unsafe_unretained) IBOutlet RoundedTextField *accountStatus;
@property (unsafe_unretained) IBOutlet NSButton *registerNameButton;
@property (unsafe_unretained) IBOutlet NSButton* photoView;
@property (unsafe_unretained) IBOutlet NSButton* passwordButton;
@property (unsafe_unretained) IBOutlet NSButton* linkDeviceButton;
@property (unsafe_unretained) IBOutlet NSButton* removeAccountButton;
@property (unsafe_unretained) IBOutlet NSButton* exportAccountButton;
@property (unsafe_unretained) IBOutlet NSImageView* addProfilePhotoImage;
@property (unsafe_unretained) IBOutlet NSTableView* devicesTableView;
@property (unsafe_unretained) IBOutlet NSTableView* blockedContactsTableView;
......@@ -89,7 +93,9 @@ QMetaObject::Connection accountStateChangedSignal;
@synthesize delegate;
@synthesize devicesTableView;
@synthesize blockedContactsTableView;
@synthesize linkDeviceButton;
@synthesize passwordField;
@synthesize exportAccountButton;
typedef NS_ENUM(NSInteger, TagViews) {
DISPLAYNAME = 100,
......@@ -114,13 +120,12 @@ typedef NS_ENUM(NSInteger, TagViews) {
- (void)awakeFromNib
{
[super awakeFromNib];
[photoView setBordered:YES];
[addProfilePhotoImage setWantsLayer: YES];
devicesTableView.delegate = self;
devicesTableView.dataSource = self;
blockedContactsTableView.delegate = self;
blockedContactsTableView.dataSource= self;
[[self view] setAutoresizingMask: NSViewMinXMargin | NSViewMaxXMargin];
[[self view] setAutoresizingMask: NSViewMinXMargin | NSViewMaxXMargin | NSViewWidthSizable];
}
- (void)viewDidLoad {
......@@ -142,7 +147,7 @@ typedef NS_ENUM(NSInteger, TagViews) {
NSImage *image = [[NSImage alloc] initWithData:imageData];
if(image) {
[photoView setBordered:NO];
[photoView setImage: [image roundCorners: 350]];
[photoView setImage: [image roundCorners: image.size.height * 0.5]];
[addProfilePhotoImage setHidden:YES];
} else {
[photoView setImage:nil];
......@@ -152,7 +157,15 @@ typedef NS_ENUM(NSInteger, TagViews) {
NSString* displayName = @(account.profileInfo.alias.c_str());
[displayNameField setStringValue:displayName];
[ringIDField setStringValue:@(account.profileInfo.uri.c_str())];
if(account.registeredName.empty()) {
lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
bool hideLocalAccountConfig = !accountProperties.managerUri.empty();
[passwordButton setHidden:hideLocalAccountConfig];
[linkDeviceButton setHidden:hideLocalAccountConfig];
[passwordField setHidden:hideLocalAccountConfig];
[exportAccountButton setHidden: hideLocalAccountConfig];
if(account.registeredName.empty() && !hideLocalAccountConfig) {
[registerNameButton setHidden:NO];
buttonRegisterWidthConstraint.constant = 260.0;
} else {
......@@ -162,7 +175,6 @@ typedef NS_ENUM(NSInteger, TagViews) {
[registeredNameField setStringValue:@(account.registeredName.c_str())];
lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
[passwordButton setTitle:accountProperties.archiveHasPassword ? @"Change password" : @"Create password"];
self.accountEnabled = account.enabled;
......@@ -241,8 +253,8 @@ typedef NS_ENUM(NSInteger, TagViews) {
}
if (auto outputImage = [picker outputImage]) {
auto image = [picker inputImage];
CGFloat newSize = MIN(image.size.height, image.size.width);
outputImage = [outputImage cropImageToSize:CGSizeMake(newSize, newSize)];
CGFloat newSize = MIN(MIN(image.size.height, image.size.width), MAX_IMAGE_SIZE);
outputImage = [outputImage imageResizeInsideMax: newSize];
[photoView setImage: [outputImage roundCorners: outputImage.size.height * 0.5]];
[photoView setBordered:NO];
[addProfilePhotoImage setHidden:YES];
......@@ -368,6 +380,7 @@ typedef NS_ENUM(NSInteger, TagViews) {
- (IBAction)editPhoto:(id)sender
{
auto pictureTaker = [IKPictureTaker pictureTaker];
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
if (@available(macOS 10.14, *)) {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if(authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied)
......@@ -384,6 +397,7 @@ typedef NS_ENUM(NSInteger, TagViews) {
}];
}
}
#endif
[pictureTaker beginPictureTakerSheetForWindow:[self.view window]
withDelegate:self
didEndSelector:@selector(pictureTakerDidEnd:returnCode:contextInfo:)
......@@ -404,10 +418,9 @@ typedef NS_ENUM(NSInteger, TagViews) {
- (IBAction)enableAccount: (NSButton *)sender {
const auto& account = accountModel->getAccountInfo(self.selectedAccountID);
self.accountModel->enableAccount(self.selectedAccountID, !account.enabled);
self.accountModel->setAccountEnabled(self.selectedAccountID, !account.enabled);
self.accountEnabled = account.enabled;
lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
self.accountModel->setAccountConfig(self.selectedAccountID, accountProperties);
}
- (IBAction)removeAccount:(id)sender
......@@ -430,14 +443,29 @@ typedef NS_ENUM(NSInteger, TagViews) {
NSSavePanel* filePicker = [NSSavePanel savePanel];
NSString* name = [@(self.selectedAccountID.c_str()) stringByAppendingString: @".gz"];
[filePicker setNameFieldStringValue: name];
if ([filePicker runModal] == NSFileHandlingPanelOKButton) {
const char* fullPath = [[filePicker URL] fileSystemRepresentation];
if (self.accountModel->exportToFile(self.selectedAccountID, fullPath)) {
[self didCompleteExportWithPath:[filePicker URL]];
} else {
[self showAlertWithTitle: @"" andText: NSLocalizedString(@"An error occured during the backup", @"Backup error")];
if ([filePicker runModal] != NSFileHandlingPanelOKButton) {
return;
}
NSString *password = @"";
const char* fullPath = [[filePicker URL] fileSystemRepresentation];
lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
if(accountProperties.archiveHasPassword) {
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:@"OK"];
[alert addButtonWithTitle:@"Cancel"];
[alert setMessageText: NSLocalizedString(@"Enter account password",
@"Backup enter password")];
NSTextField *input = [[NSSecureTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 20)];
[alert setAccessoryView:input];
if ([alert runModal] != NSAlertFirstButtonReturn) {
return;
}
password = [input stringValue];
}
if (self.accountModel->exportToFile(self.selectedAccountID, fullPath, [password UTF8String])) {
[self didCompleteExportWithPath:[filePicker URL]];
} else {
[self showAlertWithTitle: @"" andText: NSLocalizedString(@"An error occured during the backup", @"Backup error")];
}
}
......
......@@ -36,6 +36,7 @@
#import "AccSipGeneralVC.h"
#import "views/NSColor+RingTheme.h"
#import "views/NSImage+Extensions.h"
#import "Constants.h"
@interface AccSipGeneralVC ()
......@@ -76,7 +77,6 @@ typedef NS_ENUM(NSInteger, TagViews) {
-(void)viewDidLoad {
[super viewDidLoad];
[[self view] setAutoresizingMask: NSViewMinXMargin | NSViewMaxXMargin];
[photoView setBordered:YES];
[addProfilePhotoImage setWantsLayer: YES];
[self setEditingMode:NO];
[self updateView];
......@@ -93,8 +93,8 @@ typedef NS_ENUM(NSInteger, TagViews) {
if (auto outputImage = [picker outputImage]) {
[photoView setBordered:NO];
auto image = [picker inputImage];
CGFloat newSize = MIN(image.size.height, image.size.width);
outputImage = [outputImage cropImageToSize:CGSizeMake(newSize, newSize)];
CGFloat newSize = MIN(MIN(image.size.height, image.size.width), MAX_IMAGE_SIZE);
outputImage = [outputImage imageResizeInsideMax: newSize];
[photoView setImage: [outputImage roundCorners: outputImage.size.height * 0.5]];
[addProfilePhotoImage setHidden:YES];
auto imageToBytes = QByteArray::fromNSData([outputImage TIFFRepresentation]).toBase64();
......@@ -128,7 +128,7 @@ typedef NS_ENUM(NSInteger, TagViews) {
NSImage *image = [[NSImage alloc] initWithData:imageData];
if(image) {
[photoView setBordered:NO];
[photoView setImage: [image roundCorners: 350]];
[photoView setImage: [image roundCorners: image.size.height * 0.5]];
[addProfilePhotoImage setHidden:YES];
} else {
[photoView setImage:nil];
......@@ -156,6 +156,7 @@ typedef NS_ENUM(NSInteger, TagViews) {
- (IBAction)editPhoto:(id)sender
{
auto pictureTaker = [IKPictureTaker pictureTaker];
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
if (@available(macOS 10.14, *)) {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if(authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied)
......@@ -172,6 +173,7 @@ typedef NS_ENUM(NSInteger, TagViews) {
}];
}
}
#endif
[pictureTaker beginPictureTakerSheetForWindow:[self.view window]
withDelegate:self
......@@ -182,10 +184,8 @@ typedef NS_ENUM(NSInteger, TagViews) {
- (IBAction)enableAccount: (NSButton *)sender {
const auto& account = accountModel->getAccountInfo(self.selectedAccountID);
self.accountModel->enableAccount(self.selectedAccountID, !account.enabled);
self.accountModel->setAccountEnabled(self.selectedAccountID, !account.enabled);
self.accountEnabled = account.enabled;
lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
self.accountModel->setAccountConfig(self.selectedAccountID, accountProperties);
}
- (IBAction)removeAccount:(id)sender
......
/*
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#import <Cocoa/Cocoa.h>
#import "LrcModelsProtocol.h"
#import <string>
@protocol AccountBackupDelegate <NSObject>
-(void)completedWithSuccess:(BOOL) success;
-(void)showView:(NSView*)view;
@end
@interface AccountBackupVC : NSViewController <LrcModelsProtocol>
@property (retain, nonatomic) id <AccountBackupDelegate> delegate;
@property std::string accountToBackup;
-(void)show;
@end
/*
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#import "AccountBackupVC.h"
#import "Constants.h"
//LRC
#import <api/lrc.h>
#import <api/newaccountmodel.h>
@interface AccountBackupVC () {
__unsafe_unretained IBOutlet NSView* initialView;
__unsafe_unretained IBOutlet NSView* errorView;
__unsafe_unretained IBOutlet NSButton* skipBackupButton;
}
@end
@implementation AccountBackupVC
@synthesize accountModel, accountToBackup;
-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountmodel:(lrc::api::NewAccountModel*) accountModel {
if (self = [self initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{
self.accountModel = accountModel;
}
return self;
}
-(void)show {
[self.view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
[initialView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
[errorView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
BOOL skipBackup = [[NSUserDefaults standardUserDefaults] boolForKey: SkipBackUpPage];
[skipBackupButton setState: !skipBackup];
[self.delegate showView: initialView];
}
- (IBAction)skip:(id)sender
{
[self.delegate completedWithSuccess:YES];
}
- (IBAction)startAgain:(id)sender
{
[self.delegate showView: initialView];
}
- (IBAction)alwaysSkipBackup:(id)sender
{
[[NSUserDefaults standardUserDefaults] setBool:![sender state] forKey:SkipBackUpPage];
}
- (IBAction)exportAccount:(id)sender
{
NSSavePanel* filePicker = [NSSavePanel savePanel];
NSString* name = [@(self.accountToBackup.c_str()) stringByAppendingString: @".gz"];
[filePicker setNameFieldStringValue: name];
if ([filePicker runModal] != NSFileHandlingPanelOKButton) {
return;
}
NSString *password = @"";
const char* fullPath = [[filePicker URL] fileSystemRepresentation];
lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.accountToBackup);
if(accountProperties.archiveHasPassword) {
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:@"OK"];
[alert addButtonWithTitle:@"Cancel"];
[alert setMessageText: NSLocalizedString(@"Enter account password",
@"Backup enter password")];
NSTextField *input = [[NSSecureTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 20)];
[alert setAccessoryView:input];
if ([alert runModal] != NSAlertFirstButtonReturn) {
return;
}
password = [input stringValue];
}
if (self.accountModel->exportToFile(self.accountToBackup, fullPath, [password UTF8String])) {
[self.delegate completedWithSuccess:YES];
} else {
[self.delegate showView: errorView];
}
}
@end
......@@ -114,6 +114,9 @@ CGFloat const VIEW_INSET = 40;
CGRect settingsFrame = accountGeneralVC.view.frame;
settingsFrame.size.height = settingsFrame.size.height + accountAdvancedVC.view.frame.size.height;
NSView* container = [[NSView alloc] initWithFrame:settingsFrame];
CGRect advancedFrame = accountAdvancedVC.view.frame;
advancedFrame.size.width = settingsFrame.size.width;
accountAdvancedVC.view.frame = advancedFrame;
[container addSubview:accountAdvancedVC.view];
CGRect generalSettingsFrame = accountGeneralVC.view.frame;
generalSettingsFrame.origin.y = accountAdvancedVC.view.frame.size.height;
......
......@@ -21,7 +21,7 @@
#import "LrcModelsProtocol.h"
@protocol AddSIPAccountDelegate <NSObject>
- (void)didCreateAccountWithSuccess:(BOOL)success;
- (void)completedWithSuccess:(BOOL)success;
- (void)showView:(NSView*)view;
@end
......
......@@ -29,6 +29,7 @@
//ring
#import "AddSIPAccountVC.h"
#import "views/NSImage+Extensions.h"
#import "Constants.h"
@interface AddSIPAccountVC () {
__unsafe_unretained IBOutlet NSButton* photoView;
......@@ -49,7 +50,7 @@ NSTimer* timeoutTimer;
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setAutoresizingMask: NSViewHeightSizable];
[self.view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
}
-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountmodel:(lrc::api::NewAccountModel*) accountModel {
......@@ -66,11 +67,12 @@ NSTimer* timeoutTimer;
photoView.layer.masksToBounds = YES;
[photoView setBordered:YES];
[addProfilePhotoImage setWantsLayer: YES];
[self.delegate showView:self.view];
}
- (IBAction)cancel:(id)sender
{
[self.delegate didCreateAccountWithSuccess: NO];
[self.delegate completedWithSuccess: NO];
}
- (IBAction)addAccount:(id)sender
......@@ -96,7 +98,7 @@ NSTimer* timeoutTimer;
}
self.accountModel->setAccountConfig(accountID, accountProperties);
QObject::disconnect(accountCreated);
[self.delegate didCreateAccountWithSuccess: YES];
[self.delegate completedWithSuccess: YES];
});
accountToCreate = self.accountModel->createNewAccount(lrc::api::profile::Type::SIP, [displayName UTF8String], "", "", "", [userNameField.stringValue UTF8String]);
......@@ -108,13 +110,14 @@ NSTimer* timeoutTimer;
-(void) addingAccountTimeout {
QObject::disconnect(accountCreated);
[self.delegate didCreateAccountWithSuccess: YES];
[self.delegate completedWithSuccess: YES];
}
- (IBAction)editPhoto:(id)sender
{
auto pictureTaker = [IKPictureTaker pictureTaker];
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
if (@available(macOS 10.14, *)) {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if(authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied)
......@@ -131,6 +134,7 @@ NSTimer* timeoutTimer;
}];
}
}
#endif
[pictureTaker beginPictureTakerSheetForWindow:[self.delegate window]
withDelegate:self
didEndSelector:@selector(pictureTakerDidEnd:returnCode:contextInfo:)
......@@ -149,8 +153,8 @@ NSTimer* timeoutTimer;
if (auto outputImage = [picker outputImage]) {
[photoView setBordered:NO];
auto image = [picker inputImage];
CGFloat newSize = MIN(image.size.height, image.size.width);
outputImage = [outputImage cropImageToSize:CGSizeMake(newSize, newSize)];
CGFloat newSize = MIN(MIN(image.size.height, image.size.width), MAX_IMAGE_SIZE);
outputImage = [outputImage imageResizeInsideMax: newSize];
[photoView setImage:outputImage];
[addProfilePhotoImage setHidden:YES];
} else if(!photoView.image) {
......
......@@ -28,5 +28,6 @@
- (void) showMainWindow;
- (void) showDialpad;
- (BOOL) checkForRingAccount;
- (std::vector<std::string>) getActiveCalls;
@end
......@@ -21,7 +21,6 @@
#import "AppDelegate.h"
//lrc
#import <callmodel.h>
#import <api/lrc.h>
#import <api/newaccountmodel.h>
#import <api/behaviorcontroller.h>
......@@ -86,9 +85,6 @@ std::unique_ptr<lrc::api::Lrc> lrc;
#else
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
#endif
// [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
// [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSConstraintBasedLayoutLogUnsatisfiable"];
// [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"__NSConstraintBasedLayoutLogUnsatisfiable"];
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
......@@ -102,8 +98,8 @@ std::unique_ptr<lrc::api::Lrc> lrc;
NSActivityOptions options = NSActivitySuddenTerminationDisabled | NSActivityAutomaticTerminationDisabled | NSActivityBackground;
self.activity = [[NSProcessInfo processInfo] beginActivityWithOptions:options reason:@"Receiving calls and messages"];
lrc = std::make_unique<lrc::api::Lrc>();
if([self checkForRingAccount]) {
[self setRingtonePath];
[self showMainWindow];
} else {
[self showWizard];
......@@ -116,10 +112,9 @@ std::unique_ptr<lrc::api::Lrc> lrc;
SCNetworkReachabilityRef reachabilityRef = NULL;
void (^callbackBlock)(SCNetworkReachabilityFlags) = ^(SCNetworkReachabilityFlags flags) {
BOOL reachable = (flags & kSCNetworkReachabilityFlagsReachable) != 0;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
lrc->connectivityChanged();
}];
});
};
SCNetworkReachabilityContext context = {
......@@ -350,6 +345,22 @@ static void ReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNet
[self.dialpad.window makeKeyAndOrderFront:self];
}
-(std::vector<std::string>) getActiveCalls {
return lrc->activeCalls();
}
-(void)setRingtonePath {
std::vector<std::string> accounts = lrc->getAccountModel().getAccountList();
NSFileManager *fileManager = [NSFileManager defaultManager];
for (auto account: accounts) {
lrc::api::account::ConfProperties_t accountProperties = lrc->getAccountModel().getAccountConfig(account);
NSString *ringtonePath = @(accountProperties.Ringtone.ringtonePath.c_str());
if (![fileManager fileExistsAtPath: ringtonePath]) {
accountProperties.Ringtone.ringtonePath = [defaultRingtonePath() UTF8String];
lrc->getAccountModel().setAccountConfig(account, accountProperties);
}
}
}
- (BOOL) checkForRingAccount
{
......@@ -364,39 +375,6 @@ static void ReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNet
forEventClass:kInternetEventClass andEventID:kAEGetURL];
}
/**
* Recognized patterns:
* - ring:<hash>
* - ring://<hash>
*/
- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
NSString* query = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
NSURL* url = [[NSURL alloc] initWithString:query];
NSString* ringID = [url host];
if (!ringID) {
//not a valid NSURL, try to parse query directly
ringID = [query substringFromIndex:@"ring:".length];
}
// check for a valid ring hash
NSCharacterSet *hexSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789abcdefABCDEF"];
BOOL valid = [[ringID stringByTrimmingCharactersInSet:hexSet] isEqualToString:@""];
if(valid && ringID.length == 40) {
Call* c = CallModel::instance().dialingCall();
c->setDialNumber(QString::fromNSString([NSString stringWithFormat:@"ring:%@",ringID]));
c << Call::Action::ACCEPT;
} else {
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:@"OK"];
[alert setMessageText:@"Error"];
[alert setInformativeText:@"ringID cannot be read from this URL."];
[alert setAlertStyle:NSWarningAlertStyle];
[alert runModal];
}
}
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
{
if([self checkForRingAccount]) {
......@@ -425,7 +403,7 @@ static void ReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNet
}
[self.wizard close];
[self.ringWindowController close];
[[NSApplication sharedApplication] terminate:self];
lrc.reset();
}
#if ENABLE_SPARKLE
......
......@@ -18,8 +18,9 @@
*/
#import <Cocoa/Cocoa.h>
#import "LrcModelsProtocol.h"
@interface AudioPrefsVC : NSViewController <NSMenuDelegate, NSPathControlDelegate, NSOpenSavePanelDelegate> {
@interface AudioPrefsVC : NSViewController <LrcModelsProtocol> {
}
......
This diff is collapsed.
/*
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#import <Cocoa/Cocoa.h>
#include <string>
namespace lrc {
namespace api {
namespace account {
struct Info;
}
}
}
@protocol CallInConferenceVCDelegate
-(void)removePreviewForContactUri:(std::string)uri forCall:(std::string) callId;
@end
@interface CallInConferenceVC: NSViewController
-(id) initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
callId:(const std::string)callId
accountInfo:(const lrc::api::account::Info *)accInfo;
@property (retain, nonatomic) id <CallInConferenceVCDelegate> delegate;
@property std::string initiatorCallId;
@end
<
/*
* Copyright (C) 2019 Savoir-faire Linux Inc.
* Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#import "CallInConferenceVC.h"
#import "views/IconButton.h"
#import "NSString+Extensions.h"
///LRC
#import <api/newcallmodel.h>
#import <api/account.h>
#import <api/contactmodel.h>
#import <api/contact.h>
@interface CallInConferenceVC () {
std::string callUId;
const lrc::api::account::Info *accountInfo;
}
@property (unsafe_unretained) IBOutlet NSTextField* contactNameLabel;
@property (unsafe_unretained) IBOutlet NSTextField* callStateLabel;
@property (unsafe_unretained) IBOutlet IconButton* cancelCallButton;
@property QMetaObject::Connection callStateChanged;
@end
@implementation CallInConferenceVC
@synthesize cancelCallButton,callStateLabel,contactNameLabel;
-(id) initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
callId:(const std::string)callId
accountInfo:(const lrc::api::account::Info *)accInfo {
if (self = [self initWithNibName: nibNameOrNil bundle:nibBundleOrNil])
{
callUId = callId;
accountInfo = accInfo;
}