diff --git a/android/ScratchJr/app/src/main/java/org/scratchjr/android/IOManager.java b/android/ScratchJr/app/src/main/java/org/scratchjr/android/IOManager.java index 8f769cd..635d0ca 100644 --- a/android/ScratchJr/app/src/main/java/org/scratchjr/android/IOManager.java +++ b/android/ScratchJr/app/src/main/java/org/scratchjr/android/IOManager.java @@ -339,6 +339,11 @@ public class IOManager { if ("thumbnails".equals(folderName) || "sounds".equals(folderName)) { continue; } + if (activity.libraryHasAsset(fileName)) { + Log.e(LOG_TAG, "asset for " + fileName + " exists in library"); + // this is in library assets. + continue; + } String table = "characters".equals(folderName) ? "usershapes" : "userbkgs"; String statement = String.format("SELECT id FROM %s WHERE md5 = ?", table); JSONArray rows = _databaseManager.query(statement, new String[]{fileName}); diff --git a/android/ScratchJr/app/src/main/java/org/scratchjr/android/JavaScriptDirectInterface.java b/android/ScratchJr/app/src/main/java/org/scratchjr/android/JavaScriptDirectInterface.java index cf275b5..56cc90c 100644 --- a/android/ScratchJr/app/src/main/java/org/scratchjr/android/JavaScriptDirectInterface.java +++ b/android/ScratchJr/app/src/main/java/org/scratchjr/android/JavaScriptDirectInterface.java @@ -661,6 +661,11 @@ public class JavaScriptDirectInterface { } } + @JavascriptInterface + public void registerLibraryAssets(String assets) { + _activity.registerLibraryAssets(assets.split(",")); + } + @JavascriptInterface public void sendSjrUsingShareDialog(String fileName, String emailSubject, String emailBody, int shareType) { diff --git a/android/ScratchJr/app/src/main/java/org/scratchjr/android/ScratchJrActivity.java b/android/ScratchJr/app/src/main/java/org/scratchjr/android/ScratchJrActivity.java index 72a1285..59ce749 100644 --- a/android/ScratchJr/app/src/main/java/org/scratchjr/android/ScratchJrActivity.java +++ b/android/ScratchJr/app/src/main/java/org/scratchjr/android/ScratchJrActivity.java @@ -38,6 +38,7 @@ import com.google.firebase.analytics.FirebaseAnalytics; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.Vector; /** @@ -112,6 +113,13 @@ public class ScratchJrActivity */ private ArrayList projectUris = new ArrayList<>(); + /** + * This set will contain all the library assets. + * We are using set here so that we can find the asset + * whether in library in O(1) time. + */ + private final HashSet assetList = new HashSet<>(200); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -657,4 +665,21 @@ public class ScratchJrActivity } }); } + + /** + * We record all library assets names when app starts, + * so that we can know whether an asset should be marked + * as a user created one when importing. + * @param assets library asset md5 + */ + public void registerLibraryAssets(String[] assets) { + int length = assets.length; + for (int i = 0; i < length; i++) { + assetList.add(assets[i]); + } + } + + public boolean libraryHasAsset(String md5) { + return assetList.contains(md5); + } } diff --git a/ios/ScratchJr/src/IO.m b/ios/ScratchJr/src/IO.m index 8536a5f..71cae34 100644 --- a/ios/ScratchJr/src/IO.m +++ b/ios/ScratchJr/src/IO.m @@ -342,6 +342,10 @@ NSMutableDictionary *soundtimers; [fileManager copyItemAtPath:fromPath toPath:toPath error:nil]; } + if ([ScratchJr libraryHasAsset:fileName]) { + continue; + } + NSArray *parts = [path componentsSeparatedByString:@"/"]; if (parts.count > 1) { NSString *folder = parts[1]; diff --git a/ios/ScratchJr/src/JsBridge.m b/ios/ScratchJr/src/JsBridge.m index c6e66a9..f156ad2 100644 --- a/ios/ScratchJr/src/JsBridge.m +++ b/ios/ScratchJr/src/JsBridge.m @@ -207,4 +207,10 @@ [request callback:[[UIDevice currentDevice] name]]; } +- (void) registerLibraryAssets: (JsRequest *) request { + NSString *assets = request.params[0]; + [ScratchJr registerLibraryAssets: [assets componentsSeparatedByString:@","]]; + [request callback:@"1"]; +} + @end diff --git a/ios/ScratchJr/src/ScratchJr.h b/ios/ScratchJr/src/ScratchJr.h index 5a414af..fea87f5 100644 --- a/ios/ScratchJr/src/ScratchJr.h +++ b/ios/ScratchJr/src/ScratchJr.h @@ -170,4 +170,7 @@ // Imports + (void) receiveProject:(NSURL *) url; + ++ (void) registerLibraryAssets: (NSArray *)assets; ++ (BOOL) libraryHasAsset: (NSString *)md5; @end diff --git a/ios/ScratchJr/src/ScratchJr.m b/ios/ScratchJr/src/ScratchJr.m index 247f75e..ad79933 100644 --- a/ios/ScratchJr/src/ScratchJr.m +++ b/ios/ScratchJr/src/ScratchJr.m @@ -16,6 +16,8 @@ AVCaptureVideoPreviewLayer* captureVideoPreviewLayer; NSString *oncomplete; +NSMutableSet *assets; + ////////////////////////// // Init functions ///////////////////////// @@ -169,4 +171,17 @@ NSString *oncomplete; cameraMask = nil; } ++ (void) registerLibraryAssets: (NSArray *)assetArr { + if (assets == nil) { + assets = [[NSMutableSet alloc] init]; + } + for (NSString* md5 in assetArr) { + [assets addObject:md5]; + } +} + ++ (BOOL) libraryHasAsset:(NSString *)md5 { + return [assets containsObject:md5]; +} + @end diff --git a/src/entry/app.js b/src/entry/app.js index 2b4dabd..b3cfa69 100644 --- a/src/entry/app.js +++ b/src/entry/app.js @@ -41,7 +41,10 @@ window.onload = () => { preprocessAndLoadCss('css', 'css/thumbs.css'); /* For parental gate. These CSS properties should be refactored */ preprocessAndLoadCss('css', 'css/editor.css'); - entryFunction = () => OS.waitForInterface(indexMain); + entryFunction = () => OS.waitForInterface(function () { + var assets = Object.keys(MediaLib.keys).join(','); + OS.registerLibraryAssets(assets, indexMain); + }); break; case 'home': // Lobby pages diff --git a/src/tablet/Android.js b/src/tablet/Android.js index fd0eb5f..3d8e15d 100644 --- a/src/tablet/Android.js +++ b/src/tablet/Android.js @@ -254,6 +254,11 @@ export default class Android { // return 1; // } + static registerLibraryAssets (assets, fcn) { + AndroidInterface.registerLibraryAssets(assets); + fcn && fcn(); + } + // Name of the device/iPad to display on the sharing dialog page // fcn is called with the device name as an arg static deviceName (fcn) { diff --git a/src/tablet/OS.js b/src/tablet/OS.js index 8cde8e0..d8242d4 100644 --- a/src/tablet/OS.js +++ b/src/tablet/OS.js @@ -247,6 +247,10 @@ export default class OS { return 1; } + static registerLibraryAssets (assets, fcn) { + tabletInterface.registerLibraryAssets(assets, fcn); + } + // Name of the device/iPad to display on the sharing dialog page // fcn is called with the device name as an arg static deviceName (fcn) { diff --git a/src/tablet/iOS.js b/src/tablet/iOS.js index 8093987..0064be3 100644 --- a/src/tablet/iOS.js +++ b/src/tablet/iOS.js @@ -367,6 +367,13 @@ export default class iOS { iOS.call('sendSjrUsingShareDialog', fileName, emailSubject, emailBody, shareType); } + static registerLibraryAssets (assets, fcn) { + (async () => { + await iOS.call('registerLibraryAssets', assets); + fcn && fcn(); + })(); + } + // Name of the device/iPad to display on the sharing dialog page // fcn is called with the device name as an arg static deviceName (fcn) {