Skip to content

Commit

Permalink
Merge branch 'main' into fix/36196-edit-task
Browse files Browse the repository at this point in the history
  • Loading branch information
paultsimura committed Feb 21, 2024
2 parents c4dcda1 + 8d60f67 commit 2b92139
Show file tree
Hide file tree
Showing 21 changed files with 139 additions and 766 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001044305
versionName "1.4.43-5"
versionCode 1001044306
versionName "1.4.43-6"
}

flavorDimensions "default"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Manage devices
description: Control which devices can access your Expensify account
---
<div id="expensify-classic" markdown="1">

You can see which devices have been used to access your Expensify account and even remove devices that you no longer want to have access to your account.

{% include info.html %}
This process is currently not available from the mobile app and must be completed from the Expensify website.
{% include end-info.html %}

1. Hover over Settings and click **Account**.
2. Under Account Details, scroll down to the Device Management section.
3. Click **Device Management** to expand the section.
4. Review the devices that have access to your account. To remove access for a specific device, click **Revoke** next to it.

</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Set notifications
description: Select your Expensify notification preferences
---
<div id="expensify-classic" markdown="1">

{% include info.html %}
This process is currently not available from the mobile app and must be completed from the Expensify website.
{% include end-info.html %}

1. Hover over Settings and click **Account**.
2. Click the **Preferences** tab on the left.
3. Scroll down to the Contact Preferences section.
4. Select the checkbox for the types of notifications you wish to receive.
</div>
2 changes: 1 addition & 1 deletion ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.4.43.5</string>
<string>1.4.43.6</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down
2 changes: 1 addition & 1 deletion ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.4.43.5</string>
<string>1.4.43.6</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion ios/NotificationServiceExtension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<key>CFBundleShortVersionString</key>
<string>1.4.43</string>
<key>CFBundleVersion</key>
<string>1.4.43.5</string>
<string>1.4.43.6</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "1.4.43-5",
"version": "1.4.43-6",
"author": "Expensify, Inc.",
"homepage": "https://new.expensify.com",
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function AnchorRenderer({tnode, style, key}: AnchorRendererProps) {
// eslint-disable-next-line react/jsx-props-no-multi-spaces
target={htmlAttribs.target || '_blank'}
rel={htmlAttribs.rel || 'noopener noreferrer'}
style={[parentStyle, styles.textUnderlinePositionUnder, styles.textDecorationSkipInkNone, style]}
style={[style, parentStyle, styles.textUnderlinePositionUnder, styles.textDecorationSkipInkNone]}
key={key}
// Only pass the press handler for internal links. For public links or whitelisted internal links fallback to default link handling
onPress={internalNewExpensifyPath || internalExpensifyPath ? () => Link.openLink(attrHref, environmentURL, isAttachment) : undefined}
Expand Down
67 changes: 61 additions & 6 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import * as PersonalDetailsUtils from './PersonalDetailsUtils';
import * as PolicyUtils from './PolicyUtils';
import type {LastVisibleMessage} from './ReportActionsUtils';
import * as ReportActionsUtils from './ReportActionsUtils';
import shouldAllowRawHTMLMessages from './shouldAllowRawHTMLMessages';
import * as TransactionUtils from './TransactionUtils';
import * as Url from './Url';
import * as UserUtils from './UserUtils';
Expand Down Expand Up @@ -2306,7 +2307,6 @@ function getReportPreviewMessage(
isPreviewMessageForParentChatReport = false,
policy: OnyxEntry<Policy> = null,
isForListPreview = false,
shouldHidePayer = false,
): string {
const reportActionMessage = reportAction?.message?.[0].html ?? '';

Expand Down Expand Up @@ -2371,17 +2371,15 @@ function getReportPreviewMessage(
if (isSettled(report.reportID) || (report.isWaitingOnBankAccount && isPreviewMessageForParentChatReport)) {
// A settled report preview message can come in three formats "paid ... elsewhere" or "paid ... with Expensify"
let translatePhraseKey: TranslationPaths = 'iou.paidElsewhereWithAmount';
if (isPreviewMessageForParentChatReport) {
translatePhraseKey = 'iou.payerPaidAmount';
} else if (
if (
[CONST.IOU.PAYMENT_TYPE.VBBA, CONST.IOU.PAYMENT_TYPE.EXPENSIFY].some((paymentType) => paymentType === originalMessage?.paymentType) ||
!!reportActionMessage.match(/ (with Expensify|using Expensify)$/) ||
report.isWaitingOnBankAccount
) {
translatePhraseKey = 'iou.paidWithExpensifyWithAmount';
}

let actualPayerName = report.managerID === currentUserAccountID || shouldHidePayer ? '' : getDisplayNameForParticipant(report.managerID, true);
let actualPayerName = report.managerID === currentUserAccountID ? '' : getDisplayNameForParticipant(report.managerID, true);
actualPayerName = actualPayerName && isForListPreview && !isPreviewMessageForParentChatReport ? `${actualPayerName}:` : actualPayerName;
const payerDisplayName = isPreviewMessageForParentChatReport ? payerName : actualPayerName;

Expand Down Expand Up @@ -2698,7 +2696,7 @@ function hasReportNameError(report: OnyxEntry<Report>): boolean {
*/
function getParsedComment(text: string): string {
const parser = new ExpensiMark();
return text.length <= CONST.MAX_MARKUP_LENGTH ? parser.replace(text) : lodashEscape(text);
return text.length <= CONST.MAX_MARKUP_LENGTH ? parser.replace(text, {shouldEscapeText: !shouldAllowRawHTMLMessages()}) : lodashEscape(text);
}

function getReportDescriptionText(report: Report): string {
Expand Down Expand Up @@ -4731,6 +4729,62 @@ function getVisibleMemberIDs(report: OnyxEntry<Report>): number[] {
return visibleChatMemberAccountIDs;
}

/**
* Return iou report action display message
*/
function getIOUReportActionDisplayMessage(reportAction: OnyxEntry<ReportAction>): string {
if (reportAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.IOU) {
return '';
}
const originalMessage = reportAction.originalMessage;
const {IOUReportID} = originalMessage;
const iouReport = getReport(IOUReportID);
let translationKey: TranslationPaths;
if (originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.PAY) {
// The `REPORT_ACTION_TYPE.PAY` action type is used for both fulfilling existing requests and sending money. To
// differentiate between these two scenarios, we check if the `originalMessage` contains the `IOUDetails`
// property. If it does, it indicates that this is a 'Send money' action.
const {amount, currency} = originalMessage.IOUDetails ?? originalMessage;
const formattedAmount = CurrencyUtils.convertToDisplayString(Math.abs(amount), currency) ?? '';
const payerName = isExpenseReport(iouReport) ? getPolicyName(iouReport) : getDisplayNameForParticipant(iouReport?.managerID, true);

switch (originalMessage.paymentType) {
case CONST.IOU.PAYMENT_TYPE.ELSEWHERE:
translationKey = 'iou.paidElsewhereWithAmount';
break;
case CONST.IOU.PAYMENT_TYPE.EXPENSIFY:
case CONST.IOU.PAYMENT_TYPE.VBBA:
translationKey = 'iou.paidWithExpensifyWithAmount';
break;
default:
translationKey = 'iou.payerPaidAmount';
break;
}
return Localize.translateLocal(translationKey, {amount: formattedAmount, payer: payerName ?? ''});
}

const transaction = TransactionUtils.getTransaction(originalMessage.IOUTransactionID ?? '');
const transactionDetails = getTransactionDetails(!isEmptyObject(transaction) ? transaction : null);
const formattedAmount = CurrencyUtils.convertToDisplayString(transactionDetails?.amount ?? 0, transactionDetails?.currency);
const isRequestSettled = isSettled(originalMessage.IOUReportID);
const isApproved = isReportApproved(iouReport);
if (isRequestSettled) {
return Localize.translateLocal('iou.payerSettled', {
amount: formattedAmount,
});
}
if (isApproved) {
return Localize.translateLocal('iou.approvedAmount', {
amount: formattedAmount,
});
}
translationKey = ReportActionsUtils.isSplitBillAction(reportAction) ? 'iou.didSplitAmount' : 'iou.requestedAmount';
return Localize.translateLocal(translationKey, {
formattedAmount,
comment: transactionDetails?.comment ?? '',
});
}

/**
* Checks if a report is a group chat.
*
Expand Down Expand Up @@ -5169,6 +5223,7 @@ export {
hasOnlyTransactionsWithPendingRoutes,
hasNonReimbursableTransactions,
hasMissingSmartscanFields,
getIOUReportActionDisplayMessage,
isWaitingForAssigneeToCompleteTask,
isGroupChat,
isDraftExpenseReport,
Expand Down
2 changes: 1 addition & 1 deletion src/libs/actions/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1610,7 +1610,7 @@ function updateReportField(reportID: string, reportField: PolicyReportField, pre

const parameters = {
reportID,
reportFields: JSON.stringify({[reportField.fieldID]: reportField}),
reportFields: JSON.stringify({[`expensify_${reportField.fieldID}`]: reportField}),
};

API.write(WRITE_COMMANDS.SET_REPORT_FIELD, parameters, {optimisticData, failureData, successData});
Expand Down
15 changes: 5 additions & 10 deletions src/libs/migrateOnyx.js → src/libs/migrateOnyx.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
import _ from 'underscore';
import Log from './Log';
import KeyReportActionsDraftByReportActionID from './migrations/KeyReportActionsDraftByReportActionID';
import PersonalDetailsByAccountID from './migrations/PersonalDetailsByAccountID';
import RemoveEmptyReportActionsDrafts from './migrations/RemoveEmptyReportActionsDrafts';
import RenameReceiptFilename from './migrations/RenameReceiptFilename';
import TransactionBackupsToCollection from './migrations/TransactionBackupsToCollection';

export default function () {
export default function (): Promise<void> {
const startTime = Date.now();
Log.info('[Migrate Onyx] start');

return new Promise((resolve) => {
// Add all migrations to an array so they are executed in order
const migrationPromises = [PersonalDetailsByAccountID, RenameReceiptFilename, KeyReportActionsDraftByReportActionID, TransactionBackupsToCollection, RemoveEmptyReportActionsDrafts];
const migrationPromises = [RenameReceiptFilename, KeyReportActionsDraftByReportActionID, TransactionBackupsToCollection, RemoveEmptyReportActionsDrafts];

// Reduce all promises down to a single promise. All promises run in a linear fashion, waiting for the
// previous promise to finish before moving onto the next one.
/* eslint-disable arrow-body-style */
_.reduce(
migrationPromises,
(previousPromise, migrationPromise) => {
migrationPromises
.reduce((previousPromise, migrationPromise) => {
return previousPromise.then(() => {
return migrationPromise();
});
},
Promise.resolve(),
)
}, Promise.resolve())

// Once all migrations are done, resolve the main promise
.then(() => {
Expand Down
Loading

0 comments on commit 2b92139

Please sign in to comment.