react-native-macos/Libraries/Share/Share.js

164 строки
4.2 KiB
JavaScript
Исходник Обычный вид История

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
const Platform = require('../Utilities/Platform');
const invariant = require('invariant');
const processColor = require('../StyleSheet/processColor');
import NativeActionSheetManager from '../ActionSheetIOS/NativeActionSheetManager';
import NativeShareModule from './NativeShareModule';
type Content =
| {
title?: string,
message: string,
...
}
| {
title?: string,
url: string,
...
};
type Options = {
dialogTitle?: string,
excludedActivityTypes?: Array<string>,
tintColor?: string,
subject?: string,
...
};
class Share {
/**
* Open a dialog to share text content.
*
* In iOS, Returns a Promise which will be invoked an object containing `action`, `activityType`.
* If the user dismissed the dialog, the Promise will still be resolved with action being `Share.dismissedAction`
* and all the other keys being undefined.
*
* In Android, Returns a Promise which always be resolved with action being `Share.sharedAction`.
*
* ### Content
*
* - `message` - a message to share
*
* #### iOS
*
* - `url` - an URL to share
*
* At least one of URL and message is required.
*
* #### Android
*
* - `title` - title of the message
*
* ### Options
*
* #### iOS
*
* - `subject` - a subject to share via email
* - `excludedActivityTypes`
* - `tintColor`
*
* #### Android
*
* - `dialogTitle`
*
*/
static share(content: Content, options: Options = {}): Promise<Object> {
invariant(
typeof content === 'object' && content !== null,
'Content to share must be a valid object',
);
invariant(
typeof content.url === 'string' || typeof content.message === 'string',
'At least one of URL and message is required',
);
invariant(
typeof options === 'object' && options !== null,
'Options must be a valid object',
);
if (Platform.OS === 'android') {
invariant(
NativeShareModule,
'ShareModule should be registered on Android.',
);
invariant(
!content.title || typeof content.title === 'string',
'Invalid title: title should be a string.',
);
const newContent = {
title: content.title,
message:
typeof content.message === 'string' ? content.message : undefined,
};
return NativeShareModule.share(newContent, options.dialogTitle);
} else if (Platform.OS === 'ios') {
return new Promise((resolve, reject) => {
const tintColor = processColor(options.tintColor);
invariant(
tintColor == null || typeof tintColor === 'number',
'Unexpected color given for options.tintColor',
);
invariant(
NativeActionSheetManager,
'NativeActionSheetManager is not registered on iOS, but it should be.',
);
NativeActionSheetManager.showShareActionSheetWithOptions(
{
message:
typeof content.message === 'string' ? content.message : undefined,
url: typeof content.url === 'string' ? content.url : undefined,
subject: options.subject,
PlatformColor implementations for iOS and Android (#27908) Summary: This Pull Request implements the PlatformColor proposal discussed at https://github.com/react-native-community/discussions-and-proposals/issues/126. The changes include implementations for iOS and Android as well as a PlatformColorExample page in RNTester. Every native platform has the concept of system defined colors. Instead of specifying a concrete color value the app developer can choose a system color that varies in appearance depending on a system theme settings such Light or Dark mode, accessibility settings such as a High Contrast mode, and even its context within the app such as the traits of a containing view or window. The proposal is to add true platform color support to react-native by extending the Flow type `ColorValue` with platform specific color type information for each platform and to provide a convenience function, `PlatformColor()`, for instantiating platform specific ColorValue objects. `PlatformColor(name [, name ...])` where `name` is a system color name on a given platform. If `name` does not resolve to a color for any reason, the next `name` in the argument list will be resolved and so on. If none of the names resolve, a RedBox error occurs. This allows a latest platform color to be used, but if running on an older platform it will fallback to a previous version. The function returns a `ColorValue`. On iOS the values of `name` is one of the iOS [UI Element](https://developer.apple.com/documentation/uikit/uicolor/ui_element_colors) or [Standard Color](https://developer.apple.com/documentation/uikit/uicolor/standard_colors) names such as `labelColor` or `systemFillColor`. On Android the `name` values are the same [app resource](https://developer.android.com/guide/topics/resources/providing-resources) path strings that can be expressed in XML: XML Resource: `@ [<package_name>:]<resource_type>/<resource_name>` Style reference from current theme: `?[<package_name>:][<resource_type>/]<resource_name>` For example: - `?android:colorError` - `?android:attr/colorError` - `?attr/colorPrimary` - `?colorPrimaryDark` - `android:color/holo_purple` - `color/catalyst_redbox_background` On iOS another type of system dynamic color can be created using the `IOSDynamicColor({dark: <color>, light:<color>})` method. The arguments are a tuple containing custom colors for light and dark themes. Such dynamic colors are useful for branding colors or other app specific colors that still respond automatically to system setting changes. Example: `<View style={{ backgroundColor: IOSDynamicColor({light: 'black', dark: 'white'}) }}/>` Other platforms could create platform specific functions similar to `IOSDynamicColor` per the needs of those platforms. For example, macOS has a similar dynamic color type that could be implemented via a `MacDynamicColor`. On Windows custom brushes that tint or otherwise modify a system brush could be created using a platform specific method. ## Changelog [General] [Added] - Added PlatformColor implementations for iOS and Android Pull Request resolved: https://github.com/facebook/react-native/pull/27908 Test Plan: The changes have been tested using the RNTester test app for iOS and Android. On iOS a set of XCTestCase's were added to the Unit Tests. <img width="924" alt="PlatformColor-ios-android" src="https://user-images.githubusercontent.com/30053638/73472497-ff183a80-433f-11ea-90d8-2b04338bbe79.png"> In addition `PlatformColor` support has been added to other out-of-tree platforms such as macOS and Windows has been implemented using these changes: react-native for macOS branch: https://github.com/microsoft/react-native/compare/master...tom-un:tomun/platformcolors react-native for Windows branch: https://github.com/microsoft/react-native-windows/compare/master...tom-un:tomun/platformcolors iOS |Light|Dark| |{F229354502}|{F229354515}| Android |Light|Dark| |{F230114392}|{F230114490}| {F230122700} Reviewed By: hramos Differential Revision: D19837753 Pulled By: TheSavior fbshipit-source-id: 82ca70d40802f3b24591bfd4b94b61f3c38ba829
2020-03-03 02:07:50 +03:00
tintColor: typeof tintColor === 'number' ? tintColor : undefined,
excludedActivityTypes: options.excludedActivityTypes,
},
(error) => reject(error),
(success, activityType) => {
if (success) {
resolve({
action: 'sharedAction',
activityType: activityType,
});
} else {
resolve({
action: 'dismissedAction',
});
}
},
);
});
} else {
return Promise.reject(new Error('Unsupported platform'));
}
}
/**
* The content was successfully shared.
*/
static sharedAction: 'sharedAction' = 'sharedAction';
/**
* The dialog has been dismissed.
* @platform ios
*/
static dismissedAction: 'dismissedAction' = 'dismissedAction';
}
module.exports = Share;