Commit 740a5969 authored by Kateryna Kostiuk's avatar Kateryna Kostiuk

ui: export account

Use save panel to save exported account, as suggested by apple review

Change-Id: I98544588357278da6ab480dfbf450fd5d9299f92
parent 7f61fa5f
......@@ -124,8 +124,6 @@ SET(ringclient_CONTROLLERS
src/AccAdvancedRingVC.h
src/CertificateWC.mm
src/CertificateWC.h
src/BackupAccountWC.mm
src/BackupAccountWC.h
src/RestoreAccountWC.mm
src/RestoreAccountWC.h
src/AudioPrefsVC.mm
......@@ -248,7 +246,6 @@ SET(ringclient_XIBS
PreferencesWindow
RingWizard
CertificateWindow
BackupAccountWindow
RestoreAccountWindow
ExportPasswordWindow
MigrateRingAccountsWindow
......
......@@ -20,12 +20,11 @@
#import <Cocoa/Cocoa.h>
#import "LrcModelsProtocol.h"
#import "BackupAccountWC.h"
#import "RegisterNameWC.h"
#import "AccountSettingsVC.h"
#import "PasswordChangeWC.h"
@interface AccRingGeneralVC : NSViewController <NSTextFieldDelegate, LrcModelsProtocol, BackupAccountDelegate, RegisterNameDelegate, AccountGeneralProtocol, NSTableViewDelegate, NSTableViewDataSource, PasswordChangeDelegate>
@interface AccRingGeneralVC : NSViewController <NSTextFieldDelegate, LrcModelsProtocol, RegisterNameDelegate, AccountGeneralProtocol, NSTableViewDelegate, NSTableViewDataSource, PasswordChangeDelegate>
- (void) setSelectedAccount:(std::string) account;
......
......@@ -36,7 +36,6 @@
#import <interfaces/pixmapmanipulatori.h>
#import "RegisterNameWC.h"
#import "BackupAccountWC.h"
#import "views/NSColor+RingTheme.h"
#import "views/NSImage+Extensions.h"
#import "views/HoverTableRowView.h"
......@@ -428,12 +427,18 @@ typedef NS_ENUM(NSInteger, TagViews) {
- (IBAction)exportAccount:(id)sender
{
BackupAccountWC* passwordWC = [[BackupAccountWC alloc] initWithNibName:@"BackupAccountWindow" bundle: nil accountmodel: self.accountModel];
passwordWC.delegate = self;
[passwordWC setAllowFileSelection:NO];
passwordWC.selectedAccountID = self.selectedAccountID;
accountModal = passwordWC;
[self.view.window beginSheet:passwordWC.window completionHandler:nil];
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")];
}
}
}
- (IBAction)startNameRegistration:(id)sender
......
/*
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
* Author: Alexandre Lision <alexandre.lision@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 <QtCore/qdir.h>
#import "LoadingWCDelegate.h"
#import "AbstractLoadingWC.h"
#import "LrcModelsProtocol.h"
@protocol BackupAccountDelegate <LoadingWCDelegate>
@optional
-(void) didCompleteExportWithPath:(NSURL*) path;
@end
@interface BackupAccountWC : AbstractLoadingWC <LrcModelsProtocol, NSPathControlDelegate, NSOpenSavePanelDelegate>
/**
* Allow the NSPathControl of this window to select files or not
*/
@property (nonatomic) BOOL allowFileSelection;
@property std::string selectedAccountID;
@end
/*
* Copyright (C) 2016-2019 Savoir-faire Linux Inc.
* Author: Alexandre Lision <alexandre.lision@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 "BackupAccountWC.h"
//LRC
#import <api/lrc.h>
#import <api/newaccountmodel.h>
//Ring
#import "views/ITProgressIndicator.h"
@interface BackupAccountWC() <NSTextFieldDelegate> {
__unsafe_unretained IBOutlet NSPathControl* path;
__unsafe_unretained IBOutlet ITProgressIndicator* progressIndicator;
__unsafe_unretained IBOutlet NSButton* cancelButton;
}
@end
@implementation BackupAccountWC {
struct {
unsigned int didCompleteExport:1;
} delegateRespondsTo;
}
@synthesize accountModel;
-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountmodel:(lrc::api::NewAccountModel*) accountModel
{
if (self = [self initWithWindowNibName:nibNameOrNil])
{
self.accountModel= accountModel;
}
return self;
}
- (void)windowDidLoad
{
[super windowDidLoad];
NSArray * paths = NSSearchPathForDirectoriesInDomains (NSDownloadsDirectory, NSUserDomainMask, YES);
if(paths.count <= 0) {
return;
}
NSString * downloadPath = [paths objectAtIndex:0];
[path setURL: [NSURL URLWithString: downloadPath]];
}
- (void)setDelegate:(id <BackupAccountDelegate>)aDelegate
{
if (self.delegate != aDelegate) {
[super setDelegate: aDelegate];
delegateRespondsTo.didCompleteExport = [self.delegate respondsToSelector:@selector(didCompleteExportWithPath:)];
}
}
- (void) setAllowFileSelection:(BOOL) b
{
_allowFileSelection = b;
[path setAllowedTypes:_allowFileSelection ? nil : [NSArray arrayWithObject:@"public.folder"]];
}
- (IBAction)completeAction:(id)sender
{
auto finalURL = [path.URL URLByAppendingPathComponent:[@"Account_" stringByAppendingString: @(std::string(self.selectedAccountID + ".gz").c_str())]];
[self showLoading];
if (self.accountModel->exportToFile(self.selectedAccountID, finalURL.path.UTF8String)) {
if (delegateRespondsTo.didCompleteExport) {
[((id<BackupAccountDelegate>)self.delegate) didCompleteExportWithPath:finalURL];
}
[self close];
[self.window.sheetParent endSheet: self.window];
} else {
[self showError];
}
}
- (void)showLoading
{
[progressIndicator setNumberOfLines:30];
[progressIndicator setWidthOfLine:2];
[progressIndicator setLengthOfLine:5];
[progressIndicator setInnerMargin:20];
[super showLoading];
}
- (IBAction)pathControlSingleClick:(id)sender {
[path setURL:[[path clickedPathComponentCell] URL]];
}
#pragma mark - NSPathControlDelegate
- (void)pathControl:(NSPathControl *)pathControl willPopUpMenu:(NSMenu *)menu {
while ([[menu itemArray] count] >= 4) {
[menu removeItemAtIndex:3];
}
}
- (void)pathControl:(NSPathControl *)pathControl willDisplayOpenPanel:(NSOpenPanel *)openPanel
{
[openPanel setAllowsMultipleSelection:NO];
[openPanel setResolvesAliases:YES];
NSArray * paths = NSSearchPathForDirectoriesInDomains (NSDownloadsDirectory, NSUserDomainMask, YES);
if(paths.count <= 0) {
return;
}
NSString * downloadPath = [paths objectAtIndex:0];
[openPanel setDirectoryURL:[NSURL URLWithString: downloadPath]];
[openPanel setDelegate:self];
}
@end
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
<capability name="system font weights other than Regular or Bold" minToolsVersion="7.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="BackupAccountWC">
<connections>
<outlet property="errorContainer" destination="ty1-sj-tT6" id="eEy-Cr-yiw"/>
<outlet property="finalContainer" destination="XMQ-jJ-yqG" id="tI5-N3-LpJ"/>
<outlet property="initialContainer" destination="xUT-yB-g8Q" id="nwe-zs-Gxs"/>
<outlet property="path" destination="ww6-ha-GhI" id="gdx-sh-x5J"/>
<outlet property="progressContainer" destination="3Jv-gr-8Hf" id="S5k-hc-NeK"/>
<outlet property="progressIndicator" destination="Ovf-4O-7LZ" id="mq3-1b-ts5"/>
<outlet property="window" destination="QvC-M9-y7g" id="bos-rN-Jgz"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="380" height="168"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="380" height="158"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="XMQ-jJ-yqG">
<rect key="frame" x="0.0" y="0.0" width="380" height="158"/>
</customView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="3Jv-gr-8Hf">
<rect key="frame" x="0.0" y="0.0" width="380" height="158"/>
<subviews>
<customView hidden="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ovf-4O-7LZ" customClass="ITProgressIndicator">
<rect key="frame" x="155" y="44" width="70" height="70"/>
<constraints>
<constraint firstAttribute="width" constant="70" id="aK6-EW-mJE"/>
<constraint firstAttribute="height" constant="70" id="xfx-Hb-kNz"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstItem="Ovf-4O-7LZ" firstAttribute="centerX" secondItem="3Jv-gr-8Hf" secondAttribute="centerX" id="Zyc-7w-gXf"/>
<constraint firstItem="Ovf-4O-7LZ" firstAttribute="centerY" secondItem="3Jv-gr-8Hf" secondAttribute="centerY" id="dyd-7a-HdM"/>
</constraints>
</customView>
<customView hidden="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ty1-sj-tT6">
<rect key="frame" x="0.0" y="0.0" width="380" height="158"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="G1N-th-ZtP">
<rect key="frame" x="33" y="71" width="314" height="17"/>
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" alignment="center" title="An error occured during the backup" placeholderString="" id="e7n-Ev-bK7">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cxh-K7-1eh">
<rect key="frame" x="307" y="13" width="59" height="32"/>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="VN1-A3-RIh">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell>
<connections>
<action selector="cancelPressed:" target="-2" id="JTp-N4-Tb8"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="G1N-th-ZtP" firstAttribute="centerY" secondItem="ty1-sj-tT6" secondAttribute="centerY" id="79X-Dp-UYW"/>
<constraint firstAttribute="trailing" secondItem="cxh-K7-1eh" secondAttribute="trailing" constant="20" id="A86-gB-c3r"/>
<constraint firstItem="G1N-th-ZtP" firstAttribute="leading" secondItem="ty1-sj-tT6" secondAttribute="leading" constant="35" id="ajk-sQ-i5v"/>
<constraint firstAttribute="trailing" secondItem="G1N-th-ZtP" secondAttribute="trailing" constant="35" id="gLq-cd-XYE"/>
<constraint firstAttribute="bottom" secondItem="cxh-K7-1eh" secondAttribute="bottom" constant="20" id="hbG-Vx-wI4"/>
<constraint firstItem="G1N-th-ZtP" firstAttribute="centerX" secondItem="ty1-sj-tT6" secondAttribute="centerX" id="xuc-bw-qUg"/>
</constraints>
</customView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="xUT-yB-g8Q">
<rect key="frame" x="0.0" y="0.0" width="380" height="158"/>
<subviews>
<pathControl verticalHuggingPriority="750" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ww6-ha-GhI">
<rect key="frame" x="47" y="62" width="286" height="26"/>
<pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="S8N-6a-Pll">
<font key="font" metaFont="system"/>
<url key="url" string="file:///Downloads"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</pathCell>
<connections>
<action selector="pathControlSingleClick:" target="-2" id="ATY-Ld-Sok"/>
<outlet property="delegate" destination="-2" id="m1j-G8-TUK"/>
</connections>
</pathControl>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="CR7-hP-0ow">
<rect key="frame" x="33" y="101" width="329" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="16" id="0Si-aD-Fbw"/>
</constraints>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Choose where to backup your account. " placeholderString="" id="KYZ-TW-44Y">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="YtM-Br-yAx">
<rect key="frame" x="33" y="122" width="329" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="16" id="rGH-FQ-PqM"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="Export Account" id="MYh-XG-Mdn">
<font key="font" metaFont="systemSemibold" size="13"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oXB-Be-LaB">
<rect key="frame" x="307" y="13" width="59" height="32"/>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="rW5-Il-5YD">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell>
<connections>
<action selector="completeAction:" target="-2" id="4me-jZ-4mk"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Yf1-T3-fOf">
<rect key="frame" x="225" y="13" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="cSU-aD-OwX">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="cancelPressed:" target="-2" id="bIl-jp-gRS"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="CR7-hP-0ow" firstAttribute="top" secondItem="YtM-Br-yAx" secondAttribute="bottom" constant="5" id="6VO-0G-1nw"/>
<constraint firstItem="CR7-hP-0ow" firstAttribute="leading" secondItem="YtM-Br-yAx" secondAttribute="leading" id="7me-Cp-onx"/>
<constraint firstItem="ww6-ha-GhI" firstAttribute="leading" secondItem="xUT-yB-g8Q" secondAttribute="leading" constant="50" id="94f-3j-Ecs"/>
<constraint firstAttribute="trailing" secondItem="YtM-Br-yAx" secondAttribute="trailing" constant="20" id="Bch-2U-PFS"/>
<constraint firstItem="YtM-Br-yAx" firstAttribute="leading" secondItem="xUT-yB-g8Q" secondAttribute="leading" constant="35" id="Qm2-ht-q92"/>
<constraint firstItem="oXB-Be-LaB" firstAttribute="leading" secondItem="Yf1-T3-fOf" secondAttribute="trailing" constant="12" id="Tsc-ay-3Q9"/>
<constraint firstItem="YtM-Br-yAx" firstAttribute="top" secondItem="xUT-yB-g8Q" secondAttribute="top" constant="20" id="Wmj-Hw-Qf9"/>
<constraint firstAttribute="trailing" secondItem="oXB-Be-LaB" secondAttribute="trailing" constant="20" id="aTI-SX-1jI"/>
<constraint firstItem="oXB-Be-LaB" firstAttribute="top" secondItem="ww6-ha-GhI" secondAttribute="bottom" constant="25" id="gqC-9x-QYa"/>
<constraint firstAttribute="trailing" secondItem="ww6-ha-GhI" secondAttribute="trailing" constant="50" id="jfu-vK-fXY"/>
<constraint firstAttribute="trailing" secondItem="CR7-hP-0ow" secondAttribute="trailing" constant="20" id="lu3-Jz-6TR"/>
<constraint firstAttribute="bottom" secondItem="Yf1-T3-fOf" secondAttribute="bottom" constant="20" id="oCq-S8-TrF"/>
<constraint firstItem="ww6-ha-GhI" firstAttribute="top" secondItem="CR7-hP-0ow" secondAttribute="bottom" constant="15" id="tca-nk-lN4"/>
<constraint firstAttribute="bottom" secondItem="oXB-Be-LaB" secondAttribute="bottom" constant="20" id="ueM-rT-B60"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="xUT-yB-g8Q" secondAttribute="bottom" id="A5g-UN-Q8Y"/>
<constraint firstAttribute="trailing" secondItem="3Jv-gr-8Hf" secondAttribute="trailing" id="JJw-qT-SLD"/>
<constraint firstItem="3Jv-gr-8Hf" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="LCu-zR-e4t"/>
<constraint firstAttribute="trailing" secondItem="XMQ-jJ-yqG" secondAttribute="trailing" id="MO0-ux-B0L"/>
<constraint firstItem="3Jv-gr-8Hf" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="UYR-BR-G4e"/>
<constraint firstItem="xUT-yB-g8Q" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="XBA-9P-42v"/>
<constraint firstItem="ty1-sj-tT6" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="Z2j-Op-xGA"/>
<constraint firstItem="XMQ-jJ-yqG" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="aCe-zN-exF"/>
<constraint firstItem="ty1-sj-tT6" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="c0W-lm-q02"/>
<constraint firstAttribute="bottom" secondItem="XMQ-jJ-yqG" secondAttribute="bottom" id="dmX-rf-f4v"/>
<constraint firstAttribute="bottom" secondItem="3Jv-gr-8Hf" secondAttribute="bottom" id="jr4-Qd-mQ6"/>
<constraint firstAttribute="trailing" secondItem="ty1-sj-tT6" secondAttribute="trailing" id="lX9-qw-YEb"/>
<constraint firstAttribute="trailing" secondItem="xUT-yB-g8Q" secondAttribute="trailing" id="mrt-5Y-23Y"/>
<constraint firstItem="XMQ-jJ-yqG" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="tud-fv-p9U"/>
<constraint firstAttribute="bottom" secondItem="ty1-sj-tT6" secondAttribute="bottom" id="vsJ-eW-ogF"/>
<constraint firstItem="xUT-yB-g8Q" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="zTw-Zm-V44"/>
</constraints>
</view>
<connections>
<outlet property="delegate" destination="-2" id="3wn-SC-48D"/>
<outlet property="initialFirstResponder" destination="xUT-yB-g8Q" id="WGS-1O-JBF"/>
</connections>
<point key="canvasLocation" x="-439" y="-3"/>
</window>
</objects>
</document>
......@@ -195,3 +195,6 @@
/* Explanation label when user have just ID */
"This is your ID. \nCopy and share it with your friends!" = "This is your ID. \nCopy and share it with your friends!";
/* Backup error */
"An error occured during the backup" = "An error occured during the backup";
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment