From c81fca5d90af719f81041fa6b7f8fdf67de05859 Mon Sep 17 00:00:00 2001
From: Audric Ackermann <audric@loki.network>
Date: Thu, 26 Mar 2020 15:10:06 +1100
Subject: [PATCH 1/3] disnle link option on secondary device

---
 _locales/en/messages.json                       |  3 +++
 ts/components/MainViewController.tsx            |  6 +++++-
 .../session/settings/SessionSettings.tsx        | 11 +++++++++--
 .../session/settings/SessionSettingsHeader.tsx  | 17 ++++++++++-------
 4 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index e8ab82436..bacb6883e 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -1006,6 +1006,9 @@
   "noPairedDevices": {
     "message": "No paired devices"
   },
+  "deviceIsSecondaryNoPairing": {
+    "message": "This device is a secondary device and so cannot be paired."
+  },
   "allowPairing": {
     "message": "Allow Pairing"
   },
diff --git a/ts/components/MainViewController.tsx b/ts/components/MainViewController.tsx
index 2641081fa..65a906407 100644
--- a/ts/components/MainViewController.tsx
+++ b/ts/components/MainViewController.tsx
@@ -14,9 +14,13 @@ export const MainViewController = {
   },
 
   renderSettingsView: (category: SessionSettingCategory) => {
+    // tslint:disable-next-line: no-backbone-get-set-outside-model
+    const isSecondaryDevice = !!window.textsecure.storage.get(
+      'isSecondaryDevice'
+    );
     if (document.getElementById('main-view')) {
       ReactDOM.render(
-        <SettingsView category={category} />,
+        <SettingsView category={category} isSecondaryDevice={isSecondaryDevice}/>,
         document.getElementById('main-view')
       );
     }
diff --git a/ts/components/session/settings/SessionSettings.tsx b/ts/components/session/settings/SessionSettings.tsx
index 01ab4dd16..8380bc4ad 100644
--- a/ts/components/session/settings/SessionSettings.tsx
+++ b/ts/components/session/settings/SessionSettings.tsx
@@ -27,6 +27,7 @@ export enum SessionSettingType {
 
 export interface SettingsViewProps {
   category: SessionSettingCategory;
+  isSecondaryDevice: boolean;
 }
 
 interface State {
@@ -221,7 +222,7 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
   }
 
   public render() {
-    const { category } = this.props;
+    const { category, isSecondaryDevice } = this.props;
     const shouldRenderPasswordLock =
       this.state.shouldLockSettings && this.state.hasPassword;
 
@@ -230,6 +231,7 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
         <SettingsHeader
           showLinkDeviceButton={!shouldRenderPasswordLock}
           category={category}
+          isSecondaryDevice={isSecondaryDevice}
         />
 
         <div className="session-settings-view">
@@ -574,6 +576,11 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
 
   private getLinkedDeviceSettings(): Array<LocalSettingType> {
     const { linkedPubKeys } = this.state;
+    const { isSecondaryDevice } = this.props;
+    // tslint:disable-next-line: no-backbone-get-set-outside-model
+    const noPairedDeviceText = isSecondaryDevice
+      ? window.i18n('deviceIsSecondaryNoPairing')
+      : window.i18n('noPairedDevices');
 
     if (linkedPubKeys && linkedPubKeys.length > 0) {
       return linkedPubKeys.map((pubkey: any) => {
@@ -621,7 +628,7 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
       return [
         {
           id: 'no-linked-device',
-          title: window.i18n('noPairedDevices'),
+          title: noPairedDeviceText,
           type: undefined,
           description: '',
           category: SessionSettingCategory.Devices,
diff --git a/ts/components/session/settings/SessionSettingsHeader.tsx b/ts/components/session/settings/SessionSettingsHeader.tsx
index b5dc93df0..453573f44 100644
--- a/ts/components/session/settings/SessionSettingsHeader.tsx
+++ b/ts/components/session/settings/SessionSettingsHeader.tsx
@@ -6,19 +6,18 @@ import { SessionButton } from '../SessionButton';
 
 interface Props extends SettingsViewProps {
   showLinkDeviceButton: boolean | null;
-  disableLinkDeviceButton: boolean | null;
+  isSecondaryDevice: boolean;
 }
 
 export class SettingsHeader extends React.Component<Props, any> {
   public static defaultProps = {
     showLinkDeviceButton: false,
-    disableLinkDeviceButton: true,
   };
 
   public constructor(props: any) {
     super(props);
     this.state = {
-      disableLinkDeviceButton: this.props.disableLinkDeviceButton,
+      disableLinkDeviceButton: true,
     };
     this.showAddLinkedDeviceModal = this.showAddLinkedDeviceModal.bind(this);
   }
@@ -32,10 +31,12 @@ export class SettingsHeader extends React.Component<Props, any> {
   }
 
   public componentDidMount() {
-    window.Whisper.events.on('refreshLinkedDeviceList', async () => {
+    if (!this.props.isSecondaryDevice) {
+      window.Whisper.events.on('refreshLinkedDeviceList', async () => {
+        this.refreshLinkedDevice();
+      });
       this.refreshLinkedDevice();
-    });
-    this.refreshLinkedDevice();
+    }
   }
 
   public refreshLinkedDevice() {
@@ -51,7 +52,9 @@ export class SettingsHeader extends React.Component<Props, any> {
   }
 
   public componentWillUnmount() {
-    window.Whisper.events.off('refreshLinkedDeviceList');
+    if (!this.props.isSecondaryDevice) {
+      window.Whisper.events.off('refreshLinkedDeviceList');
+    }
   }
 
   public render() {

From 71cf53af15cef07d27511cc71121fb9173b80d1e Mon Sep 17 00:00:00 2001
From: Audric Ackermann <audric@loki.network>
Date: Thu, 26 Mar 2020 15:57:53 +1100
Subject: [PATCH 2/3] fix lint

---
 ts/components/MainViewController.tsx | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/ts/components/MainViewController.tsx b/ts/components/MainViewController.tsx
index 65a906407..e344920c2 100644
--- a/ts/components/MainViewController.tsx
+++ b/ts/components/MainViewController.tsx
@@ -20,7 +20,10 @@ export const MainViewController = {
     );
     if (document.getElementById('main-view')) {
       ReactDOM.render(
-        <SettingsView category={category} isSecondaryDevice={isSecondaryDevice}/>,
+        <SettingsView
+          category={category}
+          isSecondaryDevice={isSecondaryDevice}
+        />,
         document.getElementById('main-view')
       );
     }

From fa2a17c09b8c6352cddb20c9508c2f17b61877c3 Mon Sep 17 00:00:00 2001
From: Audric Ackermann <audric@loki.network>
Date: Fri, 27 Mar 2020 09:20:52 +1100
Subject: [PATCH 3/3] adress review

---
 ts/components/session/settings/SessionSettings.tsx       | 1 -
 ts/components/session/settings/SessionSettingsHeader.tsx | 4 ++++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/ts/components/session/settings/SessionSettings.tsx b/ts/components/session/settings/SessionSettings.tsx
index 8380bc4ad..b83188def 100644
--- a/ts/components/session/settings/SessionSettings.tsx
+++ b/ts/components/session/settings/SessionSettings.tsx
@@ -577,7 +577,6 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
   private getLinkedDeviceSettings(): Array<LocalSettingType> {
     const { linkedPubKeys } = this.state;
     const { isSecondaryDevice } = this.props;
-    // tslint:disable-next-line: no-backbone-get-set-outside-model
     const noPairedDeviceText = isSecondaryDevice
       ? window.i18n('deviceIsSecondaryNoPairing')
       : window.i18n('noPairedDevices');
diff --git a/ts/components/session/settings/SessionSettingsHeader.tsx b/ts/components/session/settings/SessionSettingsHeader.tsx
index 453573f44..2c14e0dbf 100644
--- a/ts/components/session/settings/SessionSettingsHeader.tsx
+++ b/ts/components/session/settings/SessionSettingsHeader.tsx
@@ -5,7 +5,9 @@ import { SessionSettingCategory, SettingsViewProps } from './SessionSettings';
 import { SessionButton } from '../SessionButton';
 
 interface Props extends SettingsViewProps {
+  // showLinkDeviceButton is used to completely hide the button while the settings password lock is displayed
   showLinkDeviceButton: boolean | null;
+  // isSecondaryDevice is used to just disable the linkDeviceButton when we are already a secondary device
   isSecondaryDevice: boolean;
 }
 
@@ -16,6 +18,8 @@ export class SettingsHeader extends React.Component<Props, any> {
 
   public constructor(props: any) {
     super(props);
+    // mark the linkDeviceButton as disabled by default.
+    // it will be enabled if needed during componentDidMount().
     this.state = {
       disableLinkDeviceButton: true,
     };