aboutsummaryrefslogtreecommitdiff
path: root/src-vue
diff options
context:
space:
mode:
authorGeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com>2023-03-02 21:28:53 +0100
committerGitHub <noreply@github.com>2023-03-02 20:28:53 +0000
commit00201de46c05a90646b072a7c3dbcf1d4c591ba6 (patch)
treea41f2cd79c9bc5bfc3e4c0e079ba97c4206cfb55 /src-vue
parentdd0aaaa0d7e2e173c8cd4110e8d5237c9b0c914a (diff)
downloadFlightCore-00201de46c05a90646b072a7c3dbcf1d4c591ba6.tar.gz
FlightCore-00201de46c05a90646b072a7c3dbcf1d4c591ba6.zip
feat: Allow installing PRs from DeveloperView (#139)
* feat: Initial backend code to get list of PRs Hardcoded for launcher right now * refactor: Autogen TS bindings from Rust code using `ts-rs` as done in #140 * fix: Fix incorrect typing What is returned is actually an array of `PullsApiResponseElement` * feat: Prototyping frontend UI for installing PR * fix: Use right repo Used Mods instead of Launcher * feat: Enable installing launcher pull request * refactor: Rename variables to indicate approp repo NorthstarLauncher vs NorthstarMods * style: Formatting fixes * feat: Initial code for getting mods PRs * feat: Add backend code for installing mods PRs * feat: Add note about launching in notification * fix: Remove commented out code * refactor: Depduplicate code * refactor: Remove unnecessary use of anyhow * refactor: Use already existing function for checking game path * feat: Add comment about profile / batch file * chore: Remove leftover print statements * feat: Add clickable link for each PR * refactor: Reduce duplicate code * refactor: Rename enum * fix: Use proper type * fix: Remove leftover `console.log`s * style: Revert accidental formatting change * refactor: Remove second API call for mods PRs * refactor: Rename variable * refactor: Remove second API call for launcher PRs * refactor: Move API URL string to `constants.rs` So that all constants are in a single place * fix: Restore lines deleted in merge * style: Formatting fixes * fix: Print line when done installing PR * feat: Show notification for install start/done Displays a notification that PR install has started and upon completion replaces it with one saying that install has completed. * fix: Remove left-over console log * feat: "Install PR" UI (#197) * refactor: export pull requests selector to dedicated component * refactor: regroup launcher+mods collapses in one collapse component * refactor: load pull requests when opening selector collapse item * refactor: review progress loaders' style * fix: don't fetch PRs if they've already been loaded * feat: update collapse style * refactor: remove fetch success notification * refactor: both collapses can be opened at the same time * fix: non-accordion collapse sends an object as event parameter * fix: Iterate over multiple pages of GitHub CI API This ensures we can still grab older artifacts. Max page is capped at 10 as going too high will cause us to hit API rate limits. Also refined error message accordingly. * refactor: Move stored PRs to submodule as suggested in review * refactor: Move getPullRequests to store submodule I order to clean up PullRequestSelector.vue Other functions will follow in separate commits. Currently TypeScript compilation fails on undefined type of `state` * fix: Properly define state type * refactor: Move installLauncherPR to store submodule * refactor: Move installModsPR to store submodule --------- Co-authored-by: Rémy Raes <contact@remyraes.com>
Diffstat (limited to 'src-vue')
-rw-r--r--src-vue/src/components/PullRequestsSelector.vue103
-rw-r--r--src-vue/src/plugins/modules/pull_requests.ts112
-rw-r--r--src-vue/src/plugins/store.ts5
-rw-r--r--src-vue/src/views/DeveloperView.vue7
4 files changed, 226 insertions, 1 deletions
diff --git a/src-vue/src/components/PullRequestsSelector.vue b/src-vue/src/components/PullRequestsSelector.vue
new file mode 100644
index 00000000..58a355f4
--- /dev/null
+++ b/src-vue/src/components/PullRequestsSelector.vue
@@ -0,0 +1,103 @@
+<template>
+ <div>
+ <el-collapse @change="onChange">
+ <el-collapse-item title="Launcher PRs" name="1">
+ <p v-if="pull_requests_launcher.length === 0">
+ <el-progress
+ :show-text="false"
+ :percentage="100"
+ status="warning"
+ :indeterminate="true"
+ :duration="1"
+ style="margin: 15px"
+ />
+ </p>
+ <el-card v-else shadow="hover" v-for="pull_request in pull_requests_launcher"
+ v-bind:key="pull_request.url">
+ <el-button type="primary" @click="installLauncherPR(pull_request)">Install</el-button>
+ <a target="_blank" :href="pull_request.html_url">
+ {{ pull_request.number }}: {{ pull_request.title }}
+ </a>
+ </el-card>
+ </el-collapse-item>
+
+ <el-collapse-item title="Mods PRs" name="2">
+ <div style="margin: 15px">
+ <el-alert title="Warning" type="warning" :closable="false" show-icon>
+ Mod PRs are installed into a separate profile. Make sure to launch via
+ 'r2ns-launch-mod-pr-version.bat' or via '-profile=R2Northstar-PR-test-managed-folder' to actually
+ run the PR version!
+ </el-alert>
+ </div>
+ <p v-if="pull_requests_mods.length === 0">
+ <el-progress
+ :show-text="false"
+ :percentage="100"
+ status="warning"
+ :indeterminate="true"
+ :duration="1"
+ style="margin: 15px"
+ />
+ </p>
+ <el-card v-else shadow="hover" v-for="pull_request in pull_requests_mods" v-bind:key="pull_request.url">
+ <el-button type="primary" @click="installModsPR(pull_request)">Install</el-button>
+ <a target="_blank" :href="pull_request.html_url">
+ {{ pull_request.number }}: {{ pull_request.title }}
+ </a>
+ </el-card>
+ </el-collapse-item>
+ </el-collapse>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue'
+import { PullRequestType } from '../../../src-tauri/bindings/PullRequestType';
+import { PullsApiResponseElement } from '../../../src-tauri/bindings/PullsApiResponseElement';
+import { invoke } from "@tauri-apps/api";
+import { ElNotification } from "element-plus";
+
+export default defineComponent({
+ name: 'PullRequestsSelector',
+ computed: {
+ pull_requests_launcher(): PullsApiResponseElement[] {
+ return this.$store.state.pullrequests.pull_requests_launcher;
+ },
+ pull_requests_mods(): PullsApiResponseElement[] {
+ return this.$store.state.pullrequests.pull_requests_mods;
+ },
+ },
+ methods: {
+ onChange(e: Object) {
+ const openedCollapseNames = Object.values(e);
+ if (openedCollapseNames.includes('1') && this.pull_requests_launcher.length === 0) {
+ this.getPullRequests('LAUNCHER');
+ }
+ if (openedCollapseNames.includes('2') && this.pull_requests_mods.length === 0) {
+ this.getPullRequests('MODS');
+ }
+ },
+ async getPullRequests(pull_request_type: PullRequestType) {
+ this.$store.commit('getPullRequests', pull_request_type);
+ },
+ async installLauncherPR(pull_request: PullsApiResponseElement) {
+ this.$store.commit('installLauncherPR', pull_request);
+ },
+ async installModsPR(pull_request: PullsApiResponseElement) {
+ this.$store.commit('installModsPR', pull_request);
+ },
+ }
+})
+</script>
+
+<style scoped>
+.el-collapse {
+ border-radius: var(--el-border-radius-base);
+ overflow: hidden;
+}
+
+:deep(.el-collapse-item__header) {
+ padding-left: 10px;
+ font-size: 14px;
+}
+</style>
diff --git a/src-vue/src/plugins/modules/pull_requests.ts b/src-vue/src/plugins/modules/pull_requests.ts
new file mode 100644
index 00000000..e64703d3
--- /dev/null
+++ b/src-vue/src/plugins/modules/pull_requests.ts
@@ -0,0 +1,112 @@
+import { ElNotification } from "element-plus";
+import { invoke } from "@tauri-apps/api";
+import { PullsApiResponseElement } from "../../../../src-tauri/bindings/PullsApiResponseElement";
+import { PullRequestType } from '../../../../src-tauri/bindings/PullRequestType';
+import { store } from "../store";
+
+interface PullRequestStoreState {
+ searchValue: string,
+ pull_requests_launcher: PullsApiResponseElement[],
+ pull_requests_mods: PullsApiResponseElement[],
+}
+
+export const pullRequestModule = {
+ state: () => ({
+ pull_requests_launcher: [],
+ pull_requests_mods: [],
+ }),
+ mutations: {
+ async getPullRequests(state: PullRequestStoreState, pull_request_type: PullRequestType) {
+ await invoke<PullsApiResponseElement[]>("get_pull_requests_wrapper", { installType: pull_request_type })
+ .then((message) => {
+ switch (pull_request_type) {
+ case "MODS":
+ state.pull_requests_mods = message;
+ break;
+
+ case "LAUNCHER":
+ state.pull_requests_launcher = message;
+ break;
+
+ default:
+ console.error("We should never end up here");
+ }
+ })
+ .catch((error) => {
+ ElNotification({
+ title: 'Error',
+ message: error,
+ type: 'error',
+ position: 'bottom-right'
+ });
+ });
+ },
+ async installLauncherPR(state: PullRequestStoreState, pull_request: PullsApiResponseElement) {
+ // Send notification telling the user to wait for the process to finish
+ const notification = ElNotification({
+ title: `Installing launcher PR ${pull_request.number}`,
+ message: 'Please wait',
+ duration: 0,
+ type: 'info',
+ position: 'bottom-right'
+ });
+
+ await invoke("apply_launcher_pr", { pullRequest: pull_request, gameInstallPath: store.state.game_path })
+ .then((message) => {
+ console.log(message);
+ // Show user notification if mod install completed.
+ ElNotification({
+ title: `Done`,
+ message: `Installed ${pull_request.number}: "${pull_request.title}"`,
+ type: 'success',
+ position: 'bottom-right'
+ });
+ })
+ .catch((error) => {
+ ElNotification({
+ title: 'Error',
+ message: error,
+ type: 'error',
+ position: 'bottom-right'
+ });
+ })
+ .finally(() => {
+ // Clear old notification
+ notification.close();
+ });
+ },
+ async installModsPR(state: PullRequestStoreState, pull_request: PullsApiResponseElement) {
+ // Send notification telling the user to wait for the process to finish
+ const notification = ElNotification({
+ title: `Installing mods PR ${pull_request.number}`,
+ message: 'Please wait',
+ duration: 0,
+ type: 'info',
+ position: 'bottom-right'
+ });
+
+ await invoke("apply_mods_pr", { pullRequest: pull_request, gameInstallPath: store.state.game_path })
+ .then((message) => {
+ // Show user notification if mod install completed.
+ ElNotification({
+ title: `Done`,
+ message: `Installed ${pull_request.number}: "${pull_request.title}"\nMake sure to launch via batch file or by specifying correct profile!`,
+ type: 'success',
+ position: 'bottom-right'
+ });
+ })
+ .catch((error) => {
+ ElNotification({
+ title: 'Error',
+ message: error,
+ type: 'error',
+ position: 'bottom-right'
+ });
+ })
+ .finally(() => {
+ // Clear old notification
+ notification.close();
+ });
+ },
+ }
+}
diff --git a/src-vue/src/plugins/store.ts b/src-vue/src/plugins/store.ts
index e44b1c3f..8671d12b 100644
--- a/src-vue/src/plugins/store.ts
+++ b/src-vue/src/plugins/store.ts
@@ -16,6 +16,8 @@ import { ReleaseInfo } from "../../../src-tauri/bindings/ReleaseInfo";
import { ThunderstoreMod } from "../../../src-tauri/bindings/ThunderstoreMod";
import { NorthstarMod } from "../../../src-tauri/bindings/NorthstarMod";
import { searchModule } from './modules/search';
+import { pullRequestModule } from './modules/pull_requests';
+import { PullsApiResponseElement } from "../../../src-tauri/bindings/PullsApiResponseElement";
const persistentStore = new Store('flight-core-settings.json');
@@ -51,7 +53,8 @@ let notification_handle: NotificationHandle;
export const store = createStore<FlightCoreStore>({
modules: {
- search: searchModule
+ search: searchModule,
+ pullrequests: pullRequestModule,
},
state(): FlightCoreStore {
return {
diff --git a/src-vue/src/views/DeveloperView.vue b/src-vue/src/views/DeveloperView.vue
index b51e1bf1..11cb4f5d 100644
--- a/src-vue/src/views/DeveloperView.vue
+++ b/src-vue/src/views/DeveloperView.vue
@@ -55,6 +55,9 @@
<el-button type="primary" @click="clearFlightCorePersistentStore">
Delete FlightCore persistent store
</el-button>
+
+ <h3>Testing</h3>
+ <pull-requests-selector />
</el-scrollbar>
</div>
</template>
@@ -66,10 +69,14 @@ import { ElNotification } from "element-plus";
import { GameInstall } from "../utils/GameInstall";
import { Store } from 'tauri-plugin-store-api';
import { ReleaseCanal } from "../utils/ReleaseCanal";
+import PullRequestsSelector from "../components/PullRequestsSelector.vue";
const persistentStore = new Store('flight-core-settings.json');
export default defineComponent({
name: "DeveloperView",
+ components: {
+ PullRequestsSelector
+ },
data() {
return {
mod_to_install_field_string : "",