diff --git a/CHANGELOG.md b/CHANGELOG.md index f4a8e57..5af714a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to the "gitea-vscode" extension will be documented in this f Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. +## [0.0.2] - 2019-04-10 +### Added: +- Configfile with token and repo properties +- Refresh button (Await HTTP Request) +- Multiple Pages +### Removed: +- Interval for updating + ## [Unreleased] - Initial release \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7d3dc31..32af58e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -251,6 +251,11 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "configparser": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/configparser/-/configparser-0.2.6.tgz", + "integrity": "sha512-u0k0Xs6CBDUcCfHHX0rMgZ4QoRQm6V3sb9AuNYkKK+4kwTlBophxBQjuVbI61vTQSRTDx4Ds7CWDQTGusf5q0A==" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", diff --git a/package.json b/package.json index f3fd7a6..0ecfe1f 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Gitea-VSCode", "description": "Gitea Issue Tracker for vs-code", "publisher": "IJustDev", - "version": "0.0.1", + "version": "0.0.2", "engines": { "vscode": "^1.32.0" }, @@ -36,14 +36,26 @@ { "command": "giteaIssues.openIssue", "title": "Show" + }, + { + "command": "giteaIssues.refreshIssues", + "title": "Refresh", + "icon": { + "dark": "resources/dark/refresh.svg", + "light": "resources/light/refresh.svg" + } + }, + { + "command": "giteaIssues.initRepo", + "title": "Initialize Gitea-Issue Tracker" } ], "menus": { - "view/item/context": [ + "view/title": [ { - "command": "giteaIssues.openIssue", - "group": "inline", - "when": "view == open-issues && viewItem == issue" + "command": "giteaIssues.refreshIssues", + "group": "navigation", + "when": "view == open-issues" } ] } @@ -64,6 +76,7 @@ "vscode": "^1.1.28" }, "dependencies": { - "axios": "^0.18.0" + "axios": "^0.18.0", + "configparser": "^0.2.6" } } \ No newline at end of file diff --git a/resources/dark/refresh.svg b/resources/dark/refresh.svg new file mode 100644 index 0000000..d79fdaa --- /dev/null +++ b/resources/dark/refresh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/light/refresh.svg b/resources/light/refresh.svg new file mode 100644 index 0000000..e034574 --- /dev/null +++ b/resources/light/refresh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/configurationProvider.ts b/src/configurationProvider.ts new file mode 100644 index 0000000..95124f3 --- /dev/null +++ b/src/configurationProvider.ts @@ -0,0 +1,37 @@ +const ConfigParser = require("configparser"); + +// import * as path from "path"; +const path = require("path"); +import * as fs from "fs"; + +export class RepositoryInformationManager { + public token(rootPath: string | undefined) { + const config = new ConfigParser(); + config.read(path.join(rootPath as string, "/.gitea/config.ini")); + return config.get("PRIVATE", "token"); + } + public repoApiUrl(rootPath: string | undefined) { + const config = new ConfigParser(); + config.read(rootPath + "/.gitea/config.ini"); + const domain = config.get("REPO", "domain"); + const repo_owner = config.get("REPO", "repo_owner"); + const repo_name = config.get("REPO", "repo_name"); + return "http://" + domain + "/api/v1/repos/" + repo_owner + "/" + repo_name + "/issues"; + } + public saveRepoInformation(rootPath: string | undefined, repoInformations: any) { + const file_path = path.join(rootPath as string, ".gitea/config.ini"); + try { + fs.mkdirSync(path.join(rootPath as string, ".gitea/")); + } catch (error) { + + } + const config = new ConfigParser(); + config.addSection("PRIVATE"); + config.addSection("REPO"); + config.set("PRIVATE", "token", repoInformations.token); + config.set("REPO", "domain", repoInformations.domain); + config.set("REPO", "repo_owner", repoInformations.repo_owner); + config.set("REPO", "repo_name", repoInformations.repo_name); + config.write(file_path); + } +} diff --git a/src/extension.ts b/src/extension.ts index 62325f8..250b5bf 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,27 +3,65 @@ import { html } from './template.html'; // Import the module and reference it with the alias vscode in your code below import * as vscode from 'vscode'; import { IssueProvider, Issue } from './issueProvider'; +import { RepositoryInformationManager } from './configurationProvider'; // this method is called when your extension is activated // your extension is activated the very first time the command is executed export function activate(context: vscode.ExtensionContext) { - const issueProvider = new IssueProvider(); - // Use the console to output diagnostic information (console.log) and errors (console.error) - // This line of code will only be executed once when your extension is activated - vscode.window.registerTreeDataProvider('open-issues', issueProvider); - vscode.commands.registerCommand('giteaIssues.openIssue', (issue: Issue) => { - const panel = vscode.window.createWebviewPanel('issue', issue.label, - vscode.ViewColumn.Active, - {}); - // panel.webview.html = "

Issue #" + issue.issueId + "!

"; - // panel.webview.html += "

Status: " + issue.issueState + "

"; - // panel.webview.html += "

Assignees: " + issue.assignee + "

"; - // panel.webview.html += "

" + issue.body + "

"; - panel.webview.html = html(issue); - }); + const issueProvider = new IssueProvider(); + // Use the console to output diagnostic information (console.log) and errors (console.error) + // This line of code will only be executed once when your extension is activated - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json + let disposable = vscode.commands.registerCommand('giteaIssues.initRepo', async () => { + if (vscode.workspace.rootPath === undefined) { + return vscode.window.showErrorMessage("No project opened!"); + } + let Token, Domain, Owner, Name; + await vscode.window.showInputBox({ + placeHolder: "Enter your gitea token here", + }).then(token => { + Token = token === undefined ? "" : token; + }); + await vscode.window.showInputBox({ + placeHolder: "Domain from your gitea server without 'https://'", + }).then(domain => { + Domain = domain === undefined ? "" : domain; + }); + await vscode.window.showInputBox({ + placeHolder: "Repository Owner", + }).then(owner => { + Owner = owner === undefined ? "" : owner; + }); + await vscode.window.showInputBox({ + placeHolder: "Repository Name", + }).then(name => { + Name = name === undefined ? "" : name; + }); + const repoInfo = { + token: Token, + domain: Domain, + repo_owner: Owner, + repo_name: Name, + }; + const rpim = new RepositoryInformationManager(); + rpim.saveRepoInformation(vscode.workspace.rootPath, repoInfo); + }); + context.subscriptions.push(disposable); + + vscode.window.registerTreeDataProvider('open-issues', issueProvider); + vscode.commands.registerCommand('giteaIssues.openIssue', (issue: Issue) => { + const panel = vscode.window.createWebviewPanel('issue', issue.label, + vscode.ViewColumn.Active, + {}); + panel.webview.html = html(issue); + }); + + vscode.commands.registerCommand('giteaIssues.refreshIssues', () => { + issueProvider.refresh(); + }); + + // The command has been defined in the package.json file + // Now provide the implementation of the command with registerCommand + // The commandId parameter must match the command field in package.json } // this method is called when your extension is deactivated diff --git a/src/issueProvider.ts b/src/issueProvider.ts index d137abe..6fd10a6 100644 --- a/src/issueProvider.ts +++ b/src/issueProvider.ts @@ -1,47 +1,67 @@ import * as vscode from "vscode"; import axios from "axios"; +import { RepositoryInformationManager } from "./configurationProvider"; export class IssueProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; - issueList: any[] = []; + issueList: Issue[] = []; - constructor() { - this.getChildrenAsync(); - const id = setInterval(() => { - if (this.issueList.length === 0) { - this._onDidChangeTreeData.fire(); - } else { - clearInterval(id); - } - }, 1 * 10); - setInterval(() => { - this._onDidChangeTreeData.fire(); - }, 10 * 1000); + async refresh() { + await this.getChildrenAsync(); + this._onDidChangeTreeData.fire(); } + constructor() { } + getTreeItem(element: Issue): vscode.TreeItem | Thenable { return element; } async getChildrenAsync() { this.issueList = []; + const repoMng = new RepositoryInformationManager(); + const repoUri = repoMng.repoApiUrl(vscode.workspace.rootPath); + console.log(repoUri); + const token = repoMng.token(vscode.workspace.rootPath); + let stop = false; for (let i = 0; i !== 10; i++) { - await axios.get("http://git.mypenink.com/api/v1/repos/MyPenInk/Frontend/issues?page=" + i, { headers: { Authorization: "token baab9fb94100c3a4f22213a0d0d0b8ce03c55bec" } }).then(res => { + await axios.get(repoUri + "?page=" + i, { headers: { Authorization: "token " + token } }).then(res => { for (const issue of res.data) { - const title = issue["title"]; const id = issue["number"]; + let isAlreadyInList = false; + this.issueList.forEach((issueOfList) => { + if (id === issueOfList.issueId) { + isAlreadyInList = true; + } + }); + if (isAlreadyInList) { + continue; + } + const title = issue["title"]; const body = issue["body"]; const state = issue["state"]; const assignee = issue["assignee"] === null ? "None" : issue["assignee"]["username"]; - const issueForList = new Issue("#" + id + " - " + title, id, body, state, assignee, "Frontend", vscode.TreeItemCollapsibleState.None); + const tmpIssue = new Issue("#" + id + " - " + title, id, body, state, assignee, "Frontend", vscode.TreeItemCollapsibleState.None); + const issueForList = new Issue(tmpIssue.label, tmpIssue.issueId, tmpIssue.body, tmpIssue.issueState, + tmpIssue.assignee, tmpIssue.firstlabel, tmpIssue.collapsibleState, { + command: 'giteaIssues.openIssue', + title: '', + arguments: [tmpIssue], + }); this.issueList.push(issueForList); } }).catch(err => { console.log(err); + stop = true; + vscode.window.showErrorMessage("Can't fetch issues; HTTP Error!"); + return; }); + if (stop) { + return; + } } console.log(this.issueList);