Skip to content

Commit 385c4a1

Browse files
authored
Added public link sharing for items (#1)
1 parent d14de19 commit 385c4a1

66 files changed

Lines changed: 2262 additions & 346 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ android {
1919
applicationId = "com.ephemeral.android"
2020
minSdk = 26
2121
targetSdk = 36
22-
versionCode = 2
23-
versionName = "0.2.0"
22+
versionCode = 4
23+
versionName = "0.2.2"
2424
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2525
}
2626

app/src/debug/java/com/ephemeral/android/data/api/FakeEphemeralApi.java

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import com.ephemeral.android.data.model.ItemType;
1111
import com.ephemeral.android.data.model.ItemTypeFilter;
1212
import com.ephemeral.android.data.model.Page;
13+
import com.ephemeral.android.data.model.PublicLink;
14+
import com.ephemeral.android.data.model.VisibilityFilter;
1315
import com.ephemeral.android.data.session.SessionRepository;
1416

1517
import 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

Comments
 (0)