Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: upload data #185

Merged
merged 17 commits into from
Jun 1, 2023
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_BASEURL=https://api.example.com
VITE_BEARERTOKEN=YOUR_BEARER_TOKEN
38 changes: 38 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@
"dependencies": {
"@electron/remote": "^2.0.9",
"@mdi/font": "^7.2.96",
"@types/dompurify": "^3.0.2",
"@types/webfontloader": "^1.6.35",
"@vue/test-utils": "^2.3.2",
"@vueuse/components": "^10.1.2",
"@vueuse/core": "^10.1.2",
"clipboardy": "^3.0.0",
"dompurify": "^3.0.3",
"randexp": "^0.5.3",
"roboto-fontface": "^0.10.0",
"tesseract.js": "^3.0.3",
Expand Down
57 changes: 18 additions & 39 deletions src/components/SettingsPrompt/SettingsPrompt.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
<v-list-item>
<v-list-item-title>
<v-text-field
v-model="accessToken"
v-model="sessionToken"
style="width: 450px"
class="pt-2"
variant="outlined"
Expand All @@ -76,7 +76,7 @@
v-bind="props"
icon="mdi-content-copy"
@click="
copyToClipboard(accessToken)
copyToClipboard(sessionToken)
"
></v-icon>
</template>
Expand Down Expand Up @@ -131,6 +131,7 @@
class="mr-4"
color="primary"
inset
:disabled="true"
></v-switch>
</template>
</v-list-item>
Expand All @@ -140,27 +141,28 @@
</template>

<script setup lang="ts">
import { Ref, ref, watch } from 'vue';
import useNotificationSystem from '@/composables/useNotificationSystem/useNotificationSystem';
import useClipboard from '@/composables/useClipboard/useClipboard';
import useTokenGenerator from '@/composables/useTokenGenerator/useTokenGenerator';
import { Ref, ref, watch } from 'vue';
import useUploadData from '@/composables/useUploadData/useUploadData';
import useSession from '@/composables/useSession/useSession';

/**
* Composables
*/
const { sessionToken, isSessionActive, startSession, stopSession } =
useSession();
const { writeClipboardText } = useClipboard();
const { defaultRules, generateValidToken } = useTokenGenerator();
const { streamData, streamRegexAndCaptureAreaSettings } = useUploadData();

/**
* Data
*/
const accessToken = ref('');
const isAccessTokenValid = ref(false);
const errorMessage: Ref<string[]> = ref([]);
const tokenVisibility = ref(false);
const isSessionActive = ref(false);
const streamData = ref(false);
const streamRegexAndCaptureAreaSettings = ref(false);

/**
* Dialog visibility
Expand All @@ -172,60 +174,37 @@ watch(
(value) => {
if (value) {
// generate token if empty
if (accessToken.value === '') {
if (sessionToken.value === '') {
regenerateAccessToken();
return;
} else {
// try to validate token if not empty
errorMessage.value = Object.values(defaultRules)
.map((rule) => rule(accessToken.value))
.map((rule) => rule(sessionToken.value))
.filter((value) => typeof value === 'string') as string[];
}
} else {
// reset validation state
const isValid = Object.values(defaultRules).every(
(rule) => rule(accessToken.value) === true
(rule) => rule(sessionToken.value) === true
);

if (isAccessTokenValid.value === isValid) {
errorMessage.value = Object.values(defaultRules)
.map((rule) => rule(accessToken.value))
.map((rule) => rule(sessionToken.value))
.filter((value) => typeof value === 'string') as string[];
}
}
}
);

watch(
() => accessToken.value,
() => sessionToken.value,
() => {
validate();
}
);

/**
* Start the session
*/
function startSession() {
isSessionActive.value = true;
// TODO: Start session functionality
useNotificationSystem().createNotification({
title: 'Session started',
});
}

/**
* Stop the session
*/
function stopSession() {
isSessionActive.value = false;
// TODO: Stop session functionality
useNotificationSystem().createNotification({
title: 'Session stopped',
type: 'info',
});
}

/**
* Function which will toggle the visibility of the access token
*/
Expand All @@ -237,21 +216,21 @@ function toggleTokenVisibility() {
* Function which will regenerate a new access token
*/
async function regenerateAccessToken() {
accessToken.value = generateValidToken();
sessionToken.value = generateValidToken();
}

/**
* Function which will validate the access token and notifies the user
*/
function validate() {
const isValid = Object.values(defaultRules).every(
(rule) => rule(accessToken.value) === true
(rule) => rule(sessionToken.value) === true
);

isAccessTokenValid.value = isValid;

errorMessage.value = Object.values(defaultRules)
.map((rule) => rule(accessToken.value))
.map((rule) => rule(sessionToken.value))
.filter((value) => typeof value === 'string') as string[];

if (!isValid && isSessionActive.value) {
Expand All @@ -274,7 +253,7 @@ function validate() {
function validateAccessToken() {
// check if the access token is valid via the defaultRules
const isValid = Object.values(defaultRules).every(
(rule) => rule(accessToken.value) === true
(rule) => rule(sessionToken.value) === true
);

if (isAccessTokenValid.value === isValid) {
Expand Down
80 changes: 80 additions & 0 deletions src/composables/useAPI/useAPI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import useNotificationSystem from '@/composables/useNotificationSystem/useNotificationSystem';

/**
* API usage composable
*/
export default function useAPI() {
/**
* Perform a GET request to the specified API endpoint.
* @param {string} endpoint - The API endpoint to fetch data from.
* @returns {Promise<object>} A Promise that resolves to the API response.
* @throws {Error} If the request fails or the response is not OK.
*/
const get = async (endpoint: string): Promise<object> => {
try {
const url = `${import.meta.env.VITE_BASEURL}/${endpoint}`;
const response = await fetch(url, {
method: 'GET',
headers: {
Authorization: `Bearer ${import.meta.env.VITE_BEARERTOKEN}`,
},
});

if (!response.ok) {
useNotificationSystem().createErrorNotification({
title: 'Failed to fetch data',
});
throw new Error('Failed to fetch data');
}

return await response.json();
} catch (error) {
useNotificationSystem().createErrorNotification({
title: 'Error occurred while fetching data',
message: `${error}`,
});
throw error;
}
};

/**
* Perform a POST request to the specified API endpoint.
* @param {string} endpoint - The API endpoint to post data to.
* @param {object} data - The data to be posted to the API.
* @returns {Promise<object>} A Promise that resolves to the API response.
* @throws {Error} If the request fails or the response is not OK.
*/
const post = async (endpoint: string, data: object): Promise<object> => {
try {
const url = `${import.meta.env.VITE_BASEURL}/${endpoint}`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${import.meta.env.VITE_BEARERTOKEN}`,
},
body: JSON.stringify(data),
});

if (!response.ok) {
useNotificationSystem().createErrorNotification({
title: 'Failed to post data',
});
throw new Error('Failed to post data');
}

return await response.json();
} catch (error) {
useNotificationSystem().createErrorNotification({
title: 'Error occurred while posting data',
message: `${error}`,
});
throw error;
}
};

return {
get,
post,
};
}
36 changes: 36 additions & 0 deletions src/composables/useSession/useSession.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ref, Ref } from 'vue';
import useNotificationSystem from '@/composables/useNotificationSystem/useNotificationSystem';

const sessionToken = ref('');
// Reactive variable to track session status
const isSessionActive: Ref<boolean> = ref(false);

export default function useSession() {
/**
* Starts the session
*/
const startSession = (): void => {
isSessionActive.value = true;
useNotificationSystem().createNotification({
title: 'Session started',
});
};

/**
* Stops the session
*/
const stopSession = (): void => {
isSessionActive.value = false;
useNotificationSystem().createNotification({
title: 'Session stopped',
type: 'info',
});
};

return {
sessionToken,
isSessionActive,
startSession,
stopSession,
};
}
Loading