diff --git a/src/FilterLists.Web.V2/src/modules/allListsTable/AllListsTable.tsx b/src/FilterLists.Web.V2/src/modules/allListsTable/AllListsTable.tsx
index fa2f5ce7d..482fb214d 100644
--- a/src/FilterLists.Web.V2/src/modules/allListsTable/AllListsTable.tsx
+++ b/src/FilterLists.Web.V2/src/modules/allListsTable/AllListsTable.tsx
@@ -1,5 +1,6 @@
import { Table } from 'antd';
import * as React from "react";
+import { SubscribeButton } from '../../shared/';
import { nameof } from '../../utils';
import { List } from './List';
@@ -29,8 +30,20 @@ export class AllListsTable extends React.Component<{}, State> {
loading={this.state.data.length > 0 ? false : true}
size="middle"
pagination={{ position: "top", size: "small" }} >
-
title="Name" dataIndex={nameof("name")} width={250} fixed="left" />
- title="Description" dataIndex={nameof("description")} />
+
+ title="Name"
+ dataIndex={nameof("name")}
+ width={250}
+ fixed="left" />
+
+ title="Description"
+ dataIndex={nameof("description")} />
+ title="Subscribe"
+ dataIndex={nameof("viewUrl")}
+ width={100}
+ fixed="right"
+ render={(text: any, record: List, index: number) => }
+ />
);
}
diff --git a/src/FilterLists.Web.V2/src/shared/SubscribeButton.tsx b/src/FilterLists.Web.V2/src/shared/SubscribeButton.tsx
new file mode 100644
index 000000000..f55794893
--- /dev/null
+++ b/src/FilterLists.Web.V2/src/shared/SubscribeButton.tsx
@@ -0,0 +1,56 @@
+import * as React from "react";
+import { Button } from 'antd';
+import { ButtonType } from "antd/lib/button";
+
+interface Props {
+ name: string;
+ url: string;
+ text?: string;
+};
+
+export const SubscribeButton = (props: Props) => {
+ let buttonType: ButtonType;
+ let titlePrefix: string;
+
+ if (props.url.indexOf(".onion/") > 0) {
+ buttonType = "ghost";
+ titlePrefix = "Tor address - ";
+ } else if (props.url.indexOf("http://") === 0) {
+ buttonType = "danger";
+ titlePrefix = "Not Secure - ";
+ } else {
+ buttonType = "primary";
+ titlePrefix = "";
+ }
+
+ const hrefTitle = `${encodeURIComponent(props.name)}`;
+ let href;
+ if (props.url.indexOf(".tpl") > 0) {
+ href = `javascript:window.external.msAddTrackingProtectionList('${encodeURIComponent(props.url)}', '${hrefTitle}')`;
+ } else if (props.url.indexOf(".lsrules") > 0) {
+ href = `x-littlesnitch:subscribe-rules?url=${encodeURIComponent(props.url)}`;
+ } else if (props.url.indexOf("?hostformat=littlesnitch") > 0) {
+ href = `x-littlesnitch:subscribe-rules?url=${encodeURIComponent(props.url)}`;
+ } else {
+ href = `abp:subscribe?location=${encodeURIComponent(props.url)}&title=${hrefTitle}`;
+ };
+
+ let title;
+ if (props.url.indexOf(".tpl") > 0) {
+ title = `${titlePrefix}Subscribe to ${props.name} with Internet Explorer's Tracking Protection List feature.`;
+ } else if (props.url.indexOf(".lsrules") > 0) {
+ title = `${titlePrefix}Subscribe to ${props.name} with Little Snitch's rule group subscription feature.`;
+ } else if (props.url.indexOf("?hostformat=littlesnitch") > 0) {
+ title = `${titlePrefix}Subscribe to ${props.name} with Little Snitch's rule group subscription feature.`;
+ } else {
+ title = `${titlePrefix}Subscribe to ${props.name} with a browser extension supporting the "abp:" protocol (e.g. uBlock Origin, Adblock Plus).`;
+ };
+
+ return props.url
+ ?
+ : null;
+};
\ No newline at end of file
diff --git a/src/FilterLists.Web.V2/src/shared/index.ts b/src/FilterLists.Web.V2/src/shared/index.ts
new file mode 100644
index 000000000..08f333155
--- /dev/null
+++ b/src/FilterLists.Web.V2/src/shared/index.ts
@@ -0,0 +1,3 @@
+import { SubscribeButton } from './SubscribeButton';
+
+export { SubscribeButton }
\ No newline at end of file