Skip to content

Commit

Permalink
[200ok-ch#932] Fixed file loading bug + cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
ieugen committed Jan 14, 2023
1 parent 2c77ba9 commit 107bfad
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 129 deletions.
2 changes: 0 additions & 2 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,4 @@
<!-- Permissions -->

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,48 @@ public static Uri pathToUri(Uri base, String path) {
}
}

public static JSObject asFileMetaData(DocumentFile d) {
if (d == null) {
throw new IllegalArgumentException("DocumentFile is null");
}
if (!d.exists()) {
throw new IllegalStateException("DocumentFile does not exist:" + d);
}
LocalDateTime date = toLocalDateTime(d.lastModified());
var o = new JSObject();
o.put("id", d.getUri().toString());
o.put("path", d.getUri().getEncodedPath());
o.put("lastModified", date.format(DateTimeFormatter.ISO_DATE_TIME));
o.put("length", d.length());
o.put("name", d.getName());
o.put("type", d.getType());
o.put("isDirectory", d.isDirectory());
o.put("isFile", d.isFile());
return o;
}

/**
* Read a document to a string.
* https://developer.android.com/training/data-storage/shared/documents-files#input_stream
*
* @param uri
* @return
* @throws IOException
*/
public static String readTextFromUri(ContentResolver resolver, Uri uri) throws IOException {
try (InputStream fis = resolver.openInputStream(uri);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis, StandardCharsets.UTF_8))) {
return reader.lines()
.collect(Collectors.joining("\n"));
}
}

static LocalDateTime toLocalDateTime(long lastModified) {
Instant i = Instant.ofEpochMilli(lastModified);
LocalDateTime date = i.atZone(ZoneId.systemDefault()).toLocalDateTime();
return date;
}

/**
* API available in JS to open the org root directory.
*
Expand Down Expand Up @@ -97,7 +139,7 @@ public void pickDirectoryResult(PluginCall call, ActivityResult result) {
// Check for the freshest data.
getActivity().getContentResolver().takePersistableUriPermission(uri, takeFlags);

var d = DocumentFile.fromTreeUri(getContext(),uri);
var d = DocumentFile.fromTreeUri(getContext(), uri);

ret.put("uri", uri);
ret.put("path", d.getUri().getEncodedPath());
Expand All @@ -111,25 +153,6 @@ public void pickDirectoryResult(PluginCall call, ActivityResult result) {
}
}

public static JSObject asFileMetaData(DocumentFile d) {
if (d == null) {
throw new IllegalArgumentException("DocumentFile is null");
}
if (!d.exists()) {
throw new IllegalStateException("DocumentFile does not exist:" + d);
}
var o = new JSObject();
o.put("id", d.getUri().toString());
o.put("path", d.getUri().getEncodedPath());
o.put("lastModified", d.lastModified());
o.put("length", d.length());
o.put("name", d.getName());
o.put("type", d.getType());
o.put("isDirectory", d.isDirectory());
o.put("isFile", d.isFile());
return o;
}

/**
* List files in a directory.
*
Expand Down Expand Up @@ -210,26 +233,6 @@ public void putFileContents(PluginCall call) {
}
}

/**
* Read a document to a string.
* https://developer.android.com/training/data-storage/shared/documents-files#input_stream
*
* @param uri
* @return
* @throws IOException
*/
public static String readTextFromUri(ContentResolver resolver, Uri uri) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
try (InputStream fis = resolver.openInputStream(uri);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis, StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
}
return stringBuilder.toString();
}

/**
* @param call
*/
Expand All @@ -243,8 +246,7 @@ public void getFileContentsAndMetadata(PluginCall call) {
ContentResolver resolver = getContext().getContentResolver();
var contents = readTextFromUri(resolver, uri);
var d = DocumentFile.fromSingleUri(getContext(), uri);
Instant i = Instant.ofEpochMilli(d.lastModified());
LocalDateTime date = i.atZone(ZoneId.systemDefault()).toLocalDateTime();
LocalDateTime date = toLocalDateTime(d.lastModified());
JSObject r = asFileMetaData(d);
r.put("contents", contents);
r.put("lastModifiedAt", date.format(DateTimeFormatter.ISO_DATE_TIME));
Expand Down Expand Up @@ -290,9 +292,9 @@ public void createFile(PluginCall call) {
// https://www.reddit.com/r/androiddev/comments/mz2j9s/comment/gw1uddt/?utm_source=share&utm_medium=web2x&context=3
var dir = DocumentFile.fromTreeUri(getContext(), fileParent);
ContentResolver resolver = getContext().getContentResolver();
Uri document = DocumentsContract.createDocument(resolver, uri , "application/octet-stream",
Uri document = DocumentsContract.createDocument(resolver, uri, "application/octet-stream",
uri.getLastPathSegment());
var file = DocumentFile.fromSingleUri(getContext(),document);
var file = DocumentFile.fromSingleUri(getContext(), document);
writeFile(resolver, file.getUri(), content);
JSObject r = asFileMetaData(dir);
call.resolve(r);
Expand All @@ -310,7 +312,7 @@ public void createFile(PluginCall call) {

private Uri removeLastPathSegment(Uri uri) {
var segments = uri.getPathSegments();
segments = segments.subList(0,segments.size()-1);
segments = segments.subList(0, segments.size() - 1);
var u = uri.buildUpon();
segments.forEach(s -> u.appendPath(s));
return u.build();
Expand Down
4 changes: 2 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ export function handleAuthenticatedSyncService(initialState) {
break;
case 'AndroidStorage':
client = createAndroidSyncBackendClient(
getPersistedField("orgDirectory"),
getPersistedField("orgDirectoryPath")
getPersistedField('orgDirectory'),
getPersistedField('orgDirectoryPath')
);
initialState.syncBackend = Map({
isAuthenticated: true,
Expand Down
4 changes: 2 additions & 2 deletions src/actions/sync_backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export const signOut = () => (dispatch, getState) => {
createGitlabOAuth().reset();
break;
case 'AndroidStorage':
persistField('orgDirectory', null);
break;
persistField('orgDirectory', null);
break;
default:
}

Expand Down
73 changes: 40 additions & 33 deletions src/components/SyncServiceSignIn/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Capacitor } from '@capacitor/core';
import React, { PureComponent, useState } from 'react';

import './stylesheet.css';
Expand All @@ -11,9 +12,7 @@ import {
gitLabProjectIdFromURL,
} from '../../sync_backend_clients/gitlab_sync_backend_client';

import {
pickDirectory,
} from '../../sync_backend_clients/android_sync_backend_client';
import { pickDirectory } from '../../sync_backend_clients/android_sync_backend_client';

import { Dropbox } from 'dropbox';
import _ from 'lodash';
Expand Down Expand Up @@ -153,6 +152,8 @@ function GitLab() {
);
}

const isNative = Capacitor.isNativePlatform();

function AndroidStorage() {
const [isVisible, setIsVisible] = useState(false);
const toggleVisible = () => setIsVisible(!isVisible);
Expand All @@ -171,7 +172,7 @@ function AndroidStorage() {
</h2>
{isVisible && (
<>
<div>
<div>
<p>
<label htmlFor="input-org-dir">Org directory:</label>
<input
Expand All @@ -184,25 +185,27 @@ function AndroidStorage() {
/>
</p>
<button
id="org-pick-directory"
name="orgDir"
onClick={(event) => {
event.preventDefault();
pickDirectory().then(result => {
const {uri, path} = result
setOrgDirectory(uri)
setOrgDirectoryPath(path)
})
}}>Choose org dir</button>
</div>
id="org-pick-directory"
name="orgDir"
onClick={(event) => {
event.preventDefault();
pickDirectory().then((result) => {
const { uri, path } = result;
setOrgDirectory(uri);
setOrgDirectoryPath(path);
});
}}
>
Choose org dir
</button>
</div>
<form
onSubmit={(event) => {
event.preventDefault();
persistField('authenticatedSyncService', 'AndroidStorage');
persistField('orgDirectory', orgDirectory);
persistField('orgDirectoryPath', orgDirectoryPath);
alert("Location:" + orgDirectoryPath);
window.location = window.location.origin + "/";
window.location = window.location.origin + '/';
}}
>
<input type="submit" value="Use selected directory" />
Expand Down Expand Up @@ -239,24 +242,28 @@ export default class SyncServiceSignIn extends PureComponent {
organice syncs your files with Dropbox, GitLab, and WebDAV.
</p>
<p className="sync-service-sign-in__help-text">Click to sign in with:</p>
{!isNative && (
<>
<div className="sync-service-container">
<a href="#dropbox" onClick={this.handleDropboxClick}>
<img src={DropboxLogo} alt="Dropbox logo" className="dropbox-logo" />
</a>
</div>

<div className="sync-service-container">
<a href="#dropbox" onClick={this.handleDropboxClick}>
<img src={DropboxLogo} alt="Dropbox logo" className="dropbox-logo" />
</a>
</div>

<div className="sync-service-container">
<GitLab />
</div>

<div className="sync-service-container">
<WebDAVForm />
</div>
<div className="sync-service-container">
<GitLab />
</div>

<div className="sync-service-container">
<AndroidStorage />
</div>
<div className="sync-service-container">
<WebDAVForm />
</div>
</>
)}
{isNative && (
<div className="sync-service-container">
<AndroidStorage />
</div>
)}

<footer className="sync-service-sign-in__help-text">
<p>
Expand Down
2 changes: 1 addition & 1 deletion src/organice_android_sync/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ import { registerPlugin } from '@capacitor/core';

const OrganiceSync = registerPlugin('OrganiceSync');

export default OrganiceSync;
export default OrganiceSync;
Loading

0 comments on commit 107bfad

Please sign in to comment.