1010import com .ephemeral .android .data .model .ItemType ;
1111import com .ephemeral .android .data .model .ItemTypeFilter ;
1212import com .ephemeral .android .data .model .Page ;
13+ import com .ephemeral .android .data .model .PublicLink ;
14+ import com .ephemeral .android .data .model .VisibilityFilter ;
1315import com .ephemeral .android .data .session .SessionRepository ;
1416
1517import java .util .ArrayList ;
@@ -28,6 +30,7 @@ public final class FakeEphemeralApi implements EphemeralApi {
2830 private final List <Item > items = new ArrayList <>();
2931 private final List <ItemEventListener > listeners = new CopyOnWriteArrayList <>();
3032 private final AtomicLong nextId = new AtomicLong (2000 );
33+ private final java .util .Map <Long , PublicLink > publicLinks = new java .util .concurrent .ConcurrentHashMap <>();
3134
3235 public FakeEphemeralApi (AppExecutors executors , SessionRepository sessionRepository ) {
3336 this .executors = executors ;
@@ -159,6 +162,17 @@ public void loadHistoryPage(HistoryQuery query, ApiCallback<Page<Item>> callback
159162 if (!q .isEmpty () && !matchesQuery (q , query .isSearchBody (), item )) {
160163 continue ;
161164 }
165+ if (query .getVisibility () == VisibilityFilter .PUBLIC ) {
166+ PublicLink pl = publicLinks .get (item .getId ());
167+ if (pl == null || !"active" .equals (pl .getStatus ())) {
168+ continue ;
169+ }
170+ } else if (query .getVisibility () == VisibilityFilter .PRIVATE ) {
171+ PublicLink pl = publicLinks .get (item .getId ());
172+ if (pl != null && "active" .equals (pl .getStatus ())) {
173+ continue ;
174+ }
175+ }
162176 filtered .add (item );
163177 }
164178 }
@@ -204,6 +218,54 @@ public Cancellable downloadFile(FileDownloadRequest request, DownloadProgressLis
204218 return cancellation ;
205219 }
206220
221+ @ Override
222+ public Cancellable downloadZip (String ids , DownloadProgressListener progress ,
223+ ApiCallback <FileDownloadResult > callback ) {
224+ UploadCancellation cancellation = new UploadCancellation ();
225+ executors .network ().execute (() -> {
226+ long total = 1024L * 512L ;
227+ for (int i = 1 ; i <= 4 ; i ++) {
228+ if (cancellation .isCanceled ()) {
229+ postError (callback , new ApiError (ApiErrorCategory .CANCELED , "Download canceled." ));
230+ return ;
231+ }
232+ long current = (total * i ) / 4 ;
233+ executors .main ().execute (() -> progress .onProgress (current , total ));
234+ sleep (120 );
235+ }
236+ executors .main ().execute (() -> callback .onSuccess (new FileDownloadResult (Uri .EMPTY , "ephemeral_download.zip" )));
237+ });
238+ return cancellation ;
239+ }
240+
241+ @ Override
242+ public void getPublicLink (long itemId , ApiCallback <PublicLink > callback ) {
243+ PublicLink link = publicLinks .get (itemId );
244+ if (link == null ) {
245+ link = new PublicLink ("none" , null , null , null );
246+ }
247+ delayedSuccess (callback , link );
248+ }
249+
250+ @ Override
251+ public void createPublicLink (long itemId , Long expiresInSeconds , ApiCallback <PublicLink > callback ) {
252+ String token = "fake_token_" + itemId ;
253+ String expiresAt = null ;
254+ if (expiresInSeconds != null ) {
255+ java .time .Instant expiry = java .time .Instant .now ().plusSeconds (expiresInSeconds );
256+ expiresAt = expiry .toString ();
257+ }
258+ PublicLink link = new PublicLink ("active" , "/share/" + token , token , expiresAt );
259+ publicLinks .put (itemId , link );
260+ delayedSuccess (callback , link );
261+ }
262+
263+ @ Override
264+ public void revokePublicLink (long itemId , ApiCallback <Void > callback ) {
265+ publicLinks .remove (itemId );
266+ delayedSuccess (callback , null );
267+ }
268+
207269 @ Override
208270 public EventSubscription observeItemEvents (ItemEventListener listener ) {
209271 listeners .add (listener );
@@ -230,6 +292,11 @@ private List<Item> filterChatItems() {
230292 }
231293 }
232294
295+ private boolean isLinkActive (long itemId ) {
296+ PublicLink pl = publicLinks .get (itemId );
297+ return pl != null && "active" .equals (pl .getStatus ());
298+ }
299+
233300 private Page <Item > page (List <Item > source , long cursor , int size ) {
234301 int start = 0 ;
235302 if (cursor > 0 ) {
@@ -241,10 +308,14 @@ private Page<Item> page(List<Item> source, long cursor, int size) {
241308 }
242309 }
243310 int end = Math .min (source .size (), start + size );
244- List <Item > pageItems = new ArrayList <>(source .subList (start , end ));
311+ List <Item > pageItems = source .subList (start , end );
312+ List <Item > mappedItems = new ArrayList <>();
313+ for (Item item : pageItems ) {
314+ mappedItems .add (item .withPublicLinkActive (isLinkActive (item .getId ())));
315+ }
245316 boolean hasMore = end < source .size ();
246- long nextCursor = hasMore && !pageItems .isEmpty () ? pageItems .get (pageItems .size () - 1 ).getId () : 0 ;
247- return new Page <>(pageItems , nextCursor , hasMore );
317+ long nextCursor = hasMore && !mappedItems .isEmpty () ? mappedItems .get (mappedItems .size () - 1 ).getId () : 0 ;
318+ return new Page <>(mappedItems , nextCursor , hasMore );
248319 }
249320
250321 private void fire (ItemEvent event ) {
@@ -266,7 +337,7 @@ private Item findItem(long itemId) {
266337
267338 private boolean matchesTypeFilter (ItemTypeFilter filter , Item item ) {
268339 if (filter == ItemTypeFilter .ALL ) {
269- return true ;
340+ return item . getType () != com . ephemeral . android . data . model . ItemType . TEXT ;
270341 }
271342 if (filter == ItemTypeFilter .IMAGES ) {
272343 return item .getType () == ItemType .IMAGE ;
0 commit comments