Skip to content

Commit

Permalink
Changed Portal Button to be off by default and hidden on mobile (#21983)
Browse files Browse the repository at this point in the history
Ref
https://linear.app/ghost/issue/DES-1074/change-portal-button-defaults-and-hide-on-mobile
- These days, themes have subscribe and account buttons built in. The
Portal Button should be opt-in rather than opt-out.
- On mobile devices, the Portal Button takes up too much valuable real
estate.
  • Loading branch information
sanne-san authored Jan 9, 2025
1 parent c7139a2 commit 2668284
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 12 deletions.
21 changes: 20 additions & 1 deletion apps/portal/src/components/TriggerButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,17 @@ export default class TriggerButton extends React.Component {
constructor(props) {
super(props);
this.state = {
width: null
width: null,
isMobile: window.innerWidth < 640
};
this.buttonRef = React.createRef();
this.handleResize = this.handleResize.bind(this);
}

componentDidMount() {
window.addEventListener('resize', this.handleResize);
this.handleResize();

setTimeout(() => {
if (this.buttonRef.current) {
const iframeElement = this.buttonRef.current.node;
Expand All @@ -237,6 +242,16 @@ export default class TriggerButton extends React.Component {
}, 0);
}

componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}

handleResize() {
this.setState({
isMobile: window.innerWidth < 640
});
}

onWidthChange(width) {
this.setState({width});
}
Expand Down Expand Up @@ -265,6 +280,10 @@ export default class TriggerButton extends React.Component {
const {portal_button: portalButton} = site;
const {showPopup, scrollbarWidth} = this.context;

if (this.state.isMobile) {
return null;
}

if (!portalButton || !isSigninAllowed({site}) || hasMode(['offerPreview'])) {
return null;
}
Expand Down
61 changes: 53 additions & 8 deletions apps/portal/src/components/TriggerButton.test.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,68 @@
import {render} from '../utils/test-utils';
import TriggerButton from './TriggerButton';

const setup = () => {
const {mockOnActionFn, ...utils} = render(
<TriggerButton />
const setup = (customProps = {}) => {
const utils = render(
<TriggerButton {...customProps} />
);

const triggerFrame = utils.getByTitle('portal-trigger');
return {
mockOnActionFn,
triggerFrame,
triggerFrame: utils.queryByTitle('portal-trigger'),
rerender: utils.rerender,
...utils
};
};

describe('Trigger Button', () => {
test('renders', () => {
const {triggerFrame} = setup();
let originalInnerWidth;

beforeEach(() => {
originalInnerWidth = window.innerWidth;
window.resizeTo = function (width) {
Object.defineProperty(window, 'innerWidth', {
configurable: true,
value: width
});
window.dispatchEvent(new Event('resize'));
};
});

afterEach(() => {
Object.defineProperty(window, 'innerWidth', {
configurable: true,
value: originalInnerWidth
});
});

test('renders when viewport is desktop size', () => {
window.resizeTo(1024);
const {triggerFrame} = setup();
expect(triggerFrame).toBeInTheDocument();
});

test('does not render when viewport is mobile size', () => {
window.resizeTo(375);
const {triggerFrame} = setup();
expect(triggerFrame).not.toBeInTheDocument();
});

test('removes itself when window is resized to mobile', () => {
window.resizeTo(1024);
const {rerender, queryByTitle} = setup();
expect(queryByTitle('portal-trigger')).toBeInTheDocument();

window.resizeTo(375);
rerender(<TriggerButton />);
expect(queryByTitle('portal-trigger')).not.toBeInTheDocument();
});

test('shows itself when window is resized to desktop', () => {
window.resizeTo(375);
const {rerender, queryByTitle} = setup();
expect(queryByTitle('portal-trigger')).not.toBeInTheDocument();

window.resizeTo(1024);
rerender(<TriggerButton />);
expect(queryByTitle('portal-trigger')).toBeInTheDocument();
});
});
2 changes: 1 addition & 1 deletion ghost/admin/mirage/fixtures/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default [

// PORTAL
setting('portal', 'portal_name', true),
setting('portal', 'portal_button', true),
setting('portal', 'portal_button', false),
setting('portal', 'portal_plans', JSON.stringify(['free'])),
setting('portal', 'portal_default_plan', 'yearly'),
setting('portal', 'portal_products', JSON.stringify([])),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@
"type": "boolean"
},
"portal_button": {
"defaultValue": "true",
"defaultValue": "false",
"validations": {
"isEmpty": false,
"isIn": [["true", "false"]]
Expand Down
2 changes: 1 addition & 1 deletion ghost/core/test/unit/server/data/schema/integrity.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('DB version integrity', function () {
// Only these variables should need updating
const currentSchemaHash = 'b26690fb57ffd0edbddb4cd9e02b17d6';
const currentFixturesHash = '80e79d1efd5da275e19cb375afb4ad04';
const currentSettingsHash = '5bf829f7e4a6b831d4c5abb33744634d';
const currentSettingsHash = '80387fdbda0102ab4995660d5d98007c';
const currentRoutesHash = '3d180d52c663d173a6be791ef411ed01';

// If this test is failing, then it is likely a change has been made that requires a DB version bump,
Expand Down

0 comments on commit 2668284

Please sign in to comment.