@@ -3,9 +3,10 @@ import fsOperation from "fileSystem";
33import Page from "components/page" ;
44import alert from "dialogs/alert" ;
55import loader from "dialogs/loader" ;
6+ import { addIntentHandler , removeIntentHandler } from "handlers/intent" ;
67import purchaseListener from "handlers/purchase" ;
78import actionStack from "lib/actionStack" ;
8- import auth from "lib/auth" ;
9+ import auth , { loginEvents } from "lib/auth" ;
910import config from "lib/config" ;
1011import installPlugin from "lib/installPlugin" ;
1112import InstallState from "lib/installState" ;
@@ -19,21 +20,19 @@ import markdownItTaskLists from "markdown-it-task-lists";
1920import { highlightCodeBlock , initHighlighting } from "utils/codeHighlight" ;
2021import helpers from "utils/helpers" ;
2122import Url from "utils/Url" ;
22- import view from "./plugin.view.js" ;
23+ import view , { cleanups } from "./plugin.view.js" ;
2324
2425let $lastPluginPage ;
2526
2627/**
2728 * Plugin page
2829 * @param {string } id
29- * @param {boolean } installed
3030 * @param {() => void } [onInstall]
3131 * @param {() => void } [onUninstall]
3232 * @param {boolean } [installOnRender]
3333 */
3434export default async function PluginInclude (
3535 id ,
36- installed ,
3736 onInstall ,
3837 onUninstall ,
3938 installOnRender ,
@@ -42,8 +41,8 @@ export default async function PluginInclude(
4241 $lastPluginPage . hide ( ) ;
4342 }
4443
45- installed = typeof installed !== "boolean" ? installed === "true" : installed ;
4644 const $page = Page ( strings [ "plugin" ] ) ;
45+ let installed = await fsOperation ( PLUGIN_DIR , id ) . exists ( ) ;
4746 let plugin = { } ;
4847 let currentVersion = "" ;
4948 let purchased = false ;
@@ -56,6 +55,8 @@ export default async function PluginInclude(
5655 let $settingsIcon ;
5756 let minVersionCode = - 1 ;
5857 let isSupported = true ;
58+ let refundHandlerSet = false ;
59+ let purchaseHandlerSet = false ;
5960
6061 actionStack . push ( {
6162 id : "plugin" ,
@@ -68,6 +69,11 @@ export default async function PluginInclude(
6869 loader . removeTitleLoader ( ) ;
6970 cancelled = true ;
7071 $lastPluginPage = null ;
72+ cleanups . forEach ( ( cleanup ) => {
73+ try {
74+ cleanup ( ) ;
75+ } catch { }
76+ } ) ;
7177 } ;
7278
7379 $lastPluginPage = $page ;
@@ -169,7 +175,11 @@ export default async function PluginInclude(
169175 remotePlugin . supported_editor ,
170176 ) ;
171177
172- if ( ! purchased && ( await helpers . checkAPIStatus ( ) ) ) {
178+ if (
179+ iap . isIapAvailable ( ) &&
180+ ! purchased &&
181+ ( await helpers . checkAPIStatus ( ) )
182+ ) {
173183 try {
174184 [ product ] = await helpers . promisify ( iap . getProducts , [
175185 remotePlugin . sku ,
@@ -252,6 +262,45 @@ export default async function PluginInclude(
252262 const $button = e . target ;
253263 const oldText = $button . textContent ;
254264
265+ try {
266+ if ( helpers . shouldAllowExternalPurchase ( ) ) {
267+ CustomTabs . open (
268+ `${ config . BASE_URL } /plugin/${ id } ?callback=app` ,
269+ { showTitle : true } ,
270+ ( ) => { } ,
271+ ( ) => { } ,
272+ ) ;
273+ if ( ! purchaseHandlerSet ) {
274+ purchaseHandlerSet = true ;
275+ const handler = async ( { module, action, value } ) => {
276+ if ( module === "plugin" && action === "purchased" && value === id ) {
277+ loader . show ( ) ;
278+
279+ try {
280+ const pluginData = await fsOperation (
281+ config . API_BASE ,
282+ `plugin/${ id } ` ,
283+ ) . readFile ( "json" ) ;
284+
285+ purchased = pluginData . owned ;
286+ render ( ) ;
287+ } catch ( error ) {
288+ window . log ( error ) ;
289+ helpers . error ( error ) ;
290+ }
291+
292+ loader . hide ( ) ;
293+ purchaseHandlerSet = false ;
294+ removeIntentHandler ( handler ) ;
295+ }
296+ } ;
297+ addIntentHandler ( handler ) ;
298+ cleanups . push ( ( ) => removeIntentHandler ( handler ) ) ;
299+ }
300+ return ;
301+ }
302+ } catch ( error ) { }
303+
255304 try {
256305 if ( ! product ) throw new Error ( "Product not found" ) ;
257306 const apiStatus = await helpers . checkAPIStatus ( ) ;
@@ -296,6 +345,38 @@ export default async function PluginInclude(
296345 async function refund ( e ) {
297346 const $button = e . target ;
298347 const oldText = $button . textContent ;
348+
349+ if ( helpers . shouldAllowExternalPurchase ( ) ) {
350+ CustomTabs . open (
351+ `${ config . BASE_URL } /plugin/${ id } ?callback=app` ,
352+ { showTitle : true } ,
353+ ( ) => { } ,
354+ ( ) => { } ,
355+ ) ;
356+
357+ if ( ! refundHandlerSet ) {
358+ refundHandlerSet = true ;
359+ const handler = ( { module, action, value } ) => {
360+ if ( module === "plugin" && action === "uninstall" && value === id ) {
361+ purchased = false ;
362+
363+ if ( installed ) {
364+ uninstall ( ) ;
365+ } else {
366+ render ( ) ;
367+ }
368+
369+ refundHandlerSet = false ;
370+ removeIntentHandler ( handler ) ;
371+ }
372+ } ;
373+
374+ addIntentHandler ( handler ) ;
375+ cleanups . push ( ( ) => removeIntentHandler ( handler ) ) ;
376+ }
377+ return ;
378+ }
379+
299380 try {
300381 if ( ! product ) throw new Error ( "Product not found" ) ;
301382 $button . textContent = strings [ "loading..." ] ;
0 commit comments