Share.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @format
  8. * @flow
  9. */
  10. 'use strict';
  11. const Platform = require('../Utilities/Platform');
  12. const invariant = require('invariant');
  13. const processColor = require('../StyleSheet/processColor');
  14. import NativeActionSheetManager from '../ActionSheetIOS/NativeActionSheetManager';
  15. import NativeShareModule from './NativeShareModule';
  16. type Content =
  17. | {
  18. title?: string,
  19. message: string,
  20. ...
  21. }
  22. | {
  23. title?: string,
  24. url: string,
  25. ...
  26. };
  27. type Options = {
  28. dialogTitle?: string,
  29. excludedActivityTypes?: Array<string>,
  30. tintColor?: string,
  31. subject?: string,
  32. ...
  33. };
  34. class Share {
  35. /**
  36. * Open a dialog to share text content.
  37. *
  38. * In iOS, Returns a Promise which will be invoked an object containing `action`, `activityType`.
  39. * If the user dismissed the dialog, the Promise will still be resolved with action being `Share.dismissedAction`
  40. * and all the other keys being undefined.
  41. *
  42. * In Android, Returns a Promise which always be resolved with action being `Share.sharedAction`.
  43. *
  44. * ### Content
  45. *
  46. * - `message` - a message to share
  47. *
  48. * #### iOS
  49. *
  50. * - `url` - an URL to share
  51. *
  52. * At least one of URL and message is required.
  53. *
  54. * #### Android
  55. *
  56. * - `title` - title of the message
  57. *
  58. * ### Options
  59. *
  60. * #### iOS
  61. *
  62. * - `subject` - a subject to share via email
  63. * - `excludedActivityTypes`
  64. * - `tintColor`
  65. *
  66. * #### Android
  67. *
  68. * - `dialogTitle`
  69. *
  70. */
  71. static share(content: Content, options: Options = {}): Promise<Object> {
  72. invariant(
  73. typeof content === 'object' && content !== null,
  74. 'Content to share must be a valid object',
  75. );
  76. invariant(
  77. typeof content.url === 'string' || typeof content.message === 'string',
  78. 'At least one of URL and message is required',
  79. );
  80. invariant(
  81. typeof options === 'object' && options !== null,
  82. 'Options must be a valid object',
  83. );
  84. if (Platform.OS === 'android') {
  85. invariant(
  86. NativeShareModule,
  87. 'ShareModule should be registered on Android.',
  88. );
  89. invariant(
  90. !content.title || typeof content.title === 'string',
  91. 'Invalid title: title should be a string.',
  92. );
  93. const newContent = {
  94. title: content.title,
  95. message:
  96. typeof content.message === 'string' ? content.message : undefined,
  97. };
  98. return NativeShareModule.share(newContent, options.dialogTitle);
  99. } else if (Platform.OS === 'ios') {
  100. return new Promise((resolve, reject) => {
  101. const tintColor = processColor(options.tintColor);
  102. invariant(
  103. tintColor == null || typeof tintColor === 'number',
  104. 'Unexpected color given for options.tintColor',
  105. );
  106. invariant(
  107. NativeActionSheetManager,
  108. 'NativeActionSheetManager is not registered on iOS, but it should be.',
  109. );
  110. NativeActionSheetManager.showShareActionSheetWithOptions(
  111. {
  112. message:
  113. typeof content.message === 'string' ? content.message : undefined,
  114. url: typeof content.url === 'string' ? content.url : undefined,
  115. subject: options.subject,
  116. tintColor: typeof tintColor === 'number' ? tintColor : undefined,
  117. excludedActivityTypes: options.excludedActivityTypes,
  118. },
  119. error => reject(error),
  120. (success, activityType) => {
  121. if (success) {
  122. resolve({
  123. action: 'sharedAction',
  124. activityType: activityType,
  125. });
  126. } else {
  127. resolve({
  128. action: 'dismissedAction',
  129. });
  130. }
  131. },
  132. );
  133. });
  134. } else {
  135. return Promise.reject(new Error('Unsupported platform'));
  136. }
  137. }
  138. /**
  139. * The content was successfully shared.
  140. */
  141. static sharedAction: 'sharedAction' = 'sharedAction';
  142. /**
  143. * The dialog has been dismissed.
  144. * @platform ios
  145. */
  146. static dismissedAction: 'dismissedAction' = 'dismissedAction';
  147. }
  148. module.exports = Share;