new: Extensions v0
This commit is contained in:
52
extension/html/index.html
Normal file
52
extension/html/index.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Hiddify Extensions</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/css/bootstrap.min.css" integrity="sha512-jnSuA4Ss2PkkikSOLtYs8BlYIeeIK1h99ty4YfvRPAlzr377vr3CXDb7sb7eEEBYjDtcYj+AjBH3FLv5uSJuXg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
|
||||
|
||||
<style>
|
||||
.monospace { font-family: monospace; }
|
||||
</style>
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-5">
|
||||
<div id="extension-list-container">
|
||||
|
||||
</div>
|
||||
|
||||
<div id="extension-page-container" style="display: none;">
|
||||
|
||||
<div id="extension-page"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal fade" id="extension-dialog" style="display: none;" tabindex="-1" aria-labelledby="modalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="modalLabel">Extension List</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="extension-page-containerdialog"></div>
|
||||
</div>
|
||||
<div class="modal-footer" id="modal-footer">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://unpkg.com/google-protobuf@3.20.1/dist/google-protobuf.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/protobufjs@7.X.X/dist/protobuf.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.bundle.min.js" integrity="sha512-7Pi/otdlbbCR+LnW+F7PwFcSDJOuUJB3OxtEHbg4vSMvzvJjde4Po1v4BR9Gdc9aXNUNFVUY+SK51wWT8WF0Gg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="rpc.js?1"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
2833
extension/html/rpc.js
Normal file
2833
extension/html/rpc.js
Normal file
File diff suppressed because it is too large
Load Diff
460
extension/html/rpc/base_pb.js
Normal file
460
extension/html/rpc/base_pb.js
Normal file
@@ -0,0 +1,460 @@
|
||||
// source: base.proto
|
||||
/**
|
||||
* @fileoverview
|
||||
* @enhanceable
|
||||
* @suppress {missingRequire} reports error on implicit type usages.
|
||||
* @suppress {messageConventions} JS Compiler reports an error if a variable or
|
||||
* field starts with 'MSG_' and isn't a translatable message.
|
||||
* @public
|
||||
*/
|
||||
// GENERATED CODE -- DO NOT EDIT!
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
var jspb = require('google-protobuf');
|
||||
var goog = jspb;
|
||||
var global =
|
||||
(typeof globalThis !== 'undefined' && globalThis) ||
|
||||
(typeof window !== 'undefined' && window) ||
|
||||
(typeof global !== 'undefined' && global) ||
|
||||
(typeof self !== 'undefined' && self) ||
|
||||
(function () { return this; }).call(null) ||
|
||||
Function('return this')();
|
||||
|
||||
goog.exportSymbol('proto.hiddifyrpc.Empty', null, global);
|
||||
goog.exportSymbol('proto.hiddifyrpc.HelloRequest', null, global);
|
||||
goog.exportSymbol('proto.hiddifyrpc.HelloResponse', null, global);
|
||||
goog.exportSymbol('proto.hiddifyrpc.ResponseCode', null, global);
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.hiddifyrpc.HelloRequest = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.hiddifyrpc.HelloRequest, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.hiddifyrpc.HelloRequest.displayName = 'proto.hiddifyrpc.HelloRequest';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.hiddifyrpc.HelloResponse = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.hiddifyrpc.HelloResponse, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.hiddifyrpc.HelloResponse.displayName = 'proto.hiddifyrpc.HelloResponse';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.hiddifyrpc.Empty = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.hiddifyrpc.Empty, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.hiddifyrpc.Empty.displayName = 'proto.hiddifyrpc.Empty';
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.hiddifyrpc.HelloRequest.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.hiddifyrpc.HelloRequest.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.hiddifyrpc.HelloRequest} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.hiddifyrpc.HelloRequest.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
name: jspb.Message.getFieldWithDefault(msg, 1, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.hiddifyrpc.HelloRequest}
|
||||
*/
|
||||
proto.hiddifyrpc.HelloRequest.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.hiddifyrpc.HelloRequest;
|
||||
return proto.hiddifyrpc.HelloRequest.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.hiddifyrpc.HelloRequest} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.hiddifyrpc.HelloRequest}
|
||||
*/
|
||||
proto.hiddifyrpc.HelloRequest.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setName(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.hiddifyrpc.HelloRequest.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.hiddifyrpc.HelloRequest.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.hiddifyrpc.HelloRequest} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.hiddifyrpc.HelloRequest.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getName();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string name = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.hiddifyrpc.HelloRequest.prototype.getName = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.hiddifyrpc.HelloRequest} returns this
|
||||
*/
|
||||
proto.hiddifyrpc.HelloRequest.prototype.setName = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.hiddifyrpc.HelloResponse.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.hiddifyrpc.HelloResponse.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.hiddifyrpc.HelloResponse} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.hiddifyrpc.HelloResponse.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
message: jspb.Message.getFieldWithDefault(msg, 1, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.hiddifyrpc.HelloResponse}
|
||||
*/
|
||||
proto.hiddifyrpc.HelloResponse.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.hiddifyrpc.HelloResponse;
|
||||
return proto.hiddifyrpc.HelloResponse.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.hiddifyrpc.HelloResponse} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.hiddifyrpc.HelloResponse}
|
||||
*/
|
||||
proto.hiddifyrpc.HelloResponse.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setMessage(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.hiddifyrpc.HelloResponse.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.hiddifyrpc.HelloResponse.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.hiddifyrpc.HelloResponse} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.hiddifyrpc.HelloResponse.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getMessage();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string message = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.hiddifyrpc.HelloResponse.prototype.getMessage = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.hiddifyrpc.HelloResponse} returns this
|
||||
*/
|
||||
proto.hiddifyrpc.HelloResponse.prototype.setMessage = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.hiddifyrpc.Empty.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.hiddifyrpc.Empty.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.hiddifyrpc.Empty} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.hiddifyrpc.Empty.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.hiddifyrpc.Empty}
|
||||
*/
|
||||
proto.hiddifyrpc.Empty.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.hiddifyrpc.Empty;
|
||||
return proto.hiddifyrpc.Empty.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.hiddifyrpc.Empty} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.hiddifyrpc.Empty}
|
||||
*/
|
||||
proto.hiddifyrpc.Empty.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.hiddifyrpc.Empty.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.hiddifyrpc.Empty.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.hiddifyrpc.Empty} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.hiddifyrpc.Empty.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
proto.hiddifyrpc.ResponseCode = {
|
||||
OK: 0,
|
||||
FAILED: 1
|
||||
};
|
||||
|
||||
goog.object.extend(exports, proto.hiddifyrpc);
|
||||
6
extension/html/rpc/client.js
Normal file
6
extension/html/rpc/client.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const extension = require("./extension_grpc_web_pb.js");
|
||||
|
||||
const grpcServerAddress = '/';
|
||||
const client = new extension.ExtensionHostServicePromiseClient(grpcServerAddress, null, null);
|
||||
|
||||
module.exports = { client ,extension};
|
||||
7
extension/html/rpc/extension.js
Normal file
7
extension/html/rpc/extension.js
Normal file
@@ -0,0 +1,7 @@
|
||||
const { listExtensions } = require('./extensionList.js');
|
||||
|
||||
window.onload = () => {
|
||||
listExtensions();
|
||||
};
|
||||
|
||||
|
||||
82
extension/html/rpc/extensionList.js
Normal file
82
extension/html/rpc/extensionList.js
Normal file
@@ -0,0 +1,82 @@
|
||||
|
||||
const { client,extension } = require('./client.js');
|
||||
async function listExtensions() {
|
||||
$("#extension-list-container").show();
|
||||
$("#extension-page-container").hide();
|
||||
|
||||
try {
|
||||
const extensionListContainer = document.getElementById('extension-list-container');
|
||||
extensionListContainer.innerHTML = ''; // Clear previous entries
|
||||
const response = await client.listExtensions(new extension.Empty(), {});
|
||||
const header = document.createElement('h1');
|
||||
header.classList.add('mb-4');
|
||||
header.textContent = "Extension List";
|
||||
extensionListContainer.appendChild(header);
|
||||
|
||||
const extensionList = response.getExtensionsList();
|
||||
extensionList.forEach(ext => {
|
||||
const listItem = createExtensionListItem(ext);
|
||||
extensionListContainer.appendChild(listItem);
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Error listing extensions:', err);
|
||||
}
|
||||
}
|
||||
|
||||
function createExtensionListItem(ext) {
|
||||
const listItem = document.createElement('li');
|
||||
listItem.className = 'list-group-item d-flex justify-content-between align-items-center';
|
||||
listItem.setAttribute('data-extension-id', ext.getId());
|
||||
|
||||
const contentDiv = document.createElement('div');
|
||||
|
||||
const titleElement = document.createElement('span');
|
||||
titleElement.innerHTML = `<strong>${ext.getTitle()}</strong>`;
|
||||
contentDiv.appendChild(titleElement);
|
||||
|
||||
const descriptionElement = document.createElement('p');
|
||||
descriptionElement.className = 'mb-0';
|
||||
descriptionElement.textContent = ext.getDescription();
|
||||
contentDiv.appendChild(descriptionElement);
|
||||
|
||||
listItem.appendChild(contentDiv);
|
||||
|
||||
const switchDiv = createSwitchElement(ext);
|
||||
listItem.appendChild(switchDiv);
|
||||
const {openExtensionPage} = require('./extensionPage.js');
|
||||
|
||||
listItem.addEventListener('click', () => openExtensionPage(ext.getId()));
|
||||
|
||||
return listItem;
|
||||
}
|
||||
|
||||
function createSwitchElement(ext) {
|
||||
const switchDiv = document.createElement('div');
|
||||
switchDiv.className = 'form-check form-switch';
|
||||
|
||||
const switchButton = document.createElement('input');
|
||||
switchButton.type = 'checkbox';
|
||||
switchButton.className = 'form-check-input';
|
||||
switchButton.checked = ext.getEnable();
|
||||
switchButton.addEventListener('change', () => toggleExtension(ext.getId(), switchButton.checked));
|
||||
|
||||
switchDiv.appendChild(switchButton);
|
||||
return switchDiv;
|
||||
}
|
||||
|
||||
async function toggleExtension(extensionId, enable) {
|
||||
const request = new extension.EditExtensionRequest();
|
||||
request.setExtensionId(extensionId);
|
||||
request.setEnable(enable);
|
||||
|
||||
try {
|
||||
await client.editExtension(request, {});
|
||||
console.log(`Extension ${extensionId} updated to ${enable ? 'enabled' : 'disabled'}`);
|
||||
} catch (err) {
|
||||
console.error('Error updating extension status:', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = { listExtensions };
|
||||
85
extension/html/rpc/extensionPage.js
Normal file
85
extension/html/rpc/extensionPage.js
Normal file
@@ -0,0 +1,85 @@
|
||||
const { client,extension } = require('./client.js');
|
||||
const { renderForm } = require('./formRenderer.js');
|
||||
const { listExtensions } = require('./extensionList.js');
|
||||
var currentExtensionId=undefined;
|
||||
function openExtensionPage(extensionId) {
|
||||
currentExtensionId=extensionId;
|
||||
$("#extension-list-container").hide();
|
||||
$("#extension-page-container").show();
|
||||
const request = new extension.ExtensionRequest();
|
||||
request.setExtensionId(extensionId);
|
||||
|
||||
const stream = client.connect(request, {});
|
||||
|
||||
stream.on('data', (response) => {
|
||||
|
||||
if (response.getExtensionId() === currentExtensionId) {
|
||||
ui=JSON.parse(response.getJsonUi())
|
||||
if(response.getType()== proto.hiddifyrpc.ExtensionResponseType.SHOW_DIALOG) {
|
||||
renderForm(ui, "dialog",handleSubmitButtonClick,handleCancelButtonClick,undefined);
|
||||
}else{
|
||||
renderForm(ui, "",handleSubmitButtonClick,handleCancelButtonClick,handleStopButtonClick);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('error', (err) => {
|
||||
console.error('Error opening extension page:', err);
|
||||
});
|
||||
|
||||
stream.on('end', () => {
|
||||
console.log('Stream ended');
|
||||
});
|
||||
}
|
||||
|
||||
async function handleSubmitButtonClick(event) {
|
||||
event.preventDefault();
|
||||
const formData = new FormData(event.target.closest('form'));
|
||||
const request = new extension.ExtensionRequest();
|
||||
|
||||
formData.forEach((value, key) => {
|
||||
request.getDataMap()[key] = value;
|
||||
});
|
||||
request.setExtensionId(currentExtensionId);
|
||||
|
||||
try {
|
||||
await client.submitForm(request, {});
|
||||
console.log('Form submitted successfully.');
|
||||
} catch (err) {
|
||||
console.error('Error submitting form:', err);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleCancelButtonClick(event) {
|
||||
event.preventDefault();
|
||||
const request = new extension.ExtensionRequest();
|
||||
request.setExtensionId(currentExtensionId);
|
||||
|
||||
try {
|
||||
await client.cancel(request, {});
|
||||
console.log('Extension cancelled successfully.');
|
||||
} catch (err) {
|
||||
console.error('Error cancelling extension:', err);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStopButtonClick(event) {
|
||||
event.preventDefault();
|
||||
const request = new extension.ExtensionRequest();
|
||||
request.setExtensionId(currentExtensionId);
|
||||
|
||||
try {
|
||||
await client.stop(request, {});
|
||||
console.log('Extension stopped successfully.');
|
||||
currentExtensionId = undefined;
|
||||
listExtensions(); // Return to the extension list
|
||||
} catch (err) {
|
||||
console.error('Error stopping extension:', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = { openExtensionPage };
|
||||
502
extension/html/rpc/extension_grpc_web_pb.js
Normal file
502
extension/html/rpc/extension_grpc_web_pb.js
Normal file
@@ -0,0 +1,502 @@
|
||||
/**
|
||||
* @fileoverview gRPC-Web generated client stub for hiddifyrpc
|
||||
* @enhanceable
|
||||
* @public
|
||||
*/
|
||||
|
||||
// Code generated by protoc-gen-grpc-web. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-grpc-web v1.5.0
|
||||
// protoc v5.28.0
|
||||
// source: extension.proto
|
||||
|
||||
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
|
||||
|
||||
const grpc = {};
|
||||
grpc.web = require('grpc-web');
|
||||
|
||||
|
||||
var base_pb = require('./base_pb.js')
|
||||
const proto = {};
|
||||
proto.hiddifyrpc = require('./extension_pb.js');
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?grpc.web.ClientOptions} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServiceClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options.format = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname.replace(/\/+$/, '');
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?grpc.web.ClientOptions} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServicePromiseClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options.format = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname.replace(/\/+$/, '');
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.hiddifyrpc.Empty,
|
||||
* !proto.hiddifyrpc.ExtensionList>}
|
||||
*/
|
||||
const methodDescriptor_ExtensionHostService_ListExtensions = new grpc.web.MethodDescriptor(
|
||||
'/hiddifyrpc.ExtensionHostService/ListExtensions',
|
||||
grpc.web.MethodType.UNARY,
|
||||
base_pb.Empty,
|
||||
proto.hiddifyrpc.ExtensionList,
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.Empty} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.hiddifyrpc.ExtensionList.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.Empty} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.hiddifyrpc.ExtensionList)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.hiddifyrpc.ExtensionList>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServiceClient.prototype.listExtensions =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/ListExtensions',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_ListExtensions,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.Empty} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.hiddifyrpc.ExtensionList>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServicePromiseClient.prototype.listExtensions =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/ListExtensions',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_ListExtensions);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.hiddifyrpc.ExtensionRequest,
|
||||
* !proto.hiddifyrpc.ExtensionResponse>}
|
||||
*/
|
||||
const methodDescriptor_ExtensionHostService_Connect = new grpc.web.MethodDescriptor(
|
||||
'/hiddifyrpc.ExtensionHostService/Connect',
|
||||
grpc.web.MethodType.SERVER_STREAMING,
|
||||
proto.hiddifyrpc.ExtensionRequest,
|
||||
proto.hiddifyrpc.ExtensionResponse,
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.hiddifyrpc.ExtensionResponse.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request The request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.hiddifyrpc.ExtensionResponse>}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServiceClient.prototype.connect =
|
||||
function(request, metadata) {
|
||||
return this.client_.serverStreaming(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/Connect',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_Connect);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request The request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.hiddifyrpc.ExtensionResponse>}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServicePromiseClient.prototype.connect =
|
||||
function(request, metadata) {
|
||||
return this.client_.serverStreaming(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/Connect',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_Connect);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.hiddifyrpc.EditExtensionRequest,
|
||||
* !proto.hiddifyrpc.ExtensionActionResult>}
|
||||
*/
|
||||
const methodDescriptor_ExtensionHostService_EditExtension = new grpc.web.MethodDescriptor(
|
||||
'/hiddifyrpc.ExtensionHostService/EditExtension',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.hiddifyrpc.EditExtensionRequest,
|
||||
proto.hiddifyrpc.ExtensionActionResult,
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.EditExtensionRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.hiddifyrpc.ExtensionActionResult.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.EditExtensionRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.hiddifyrpc.ExtensionActionResult)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.hiddifyrpc.ExtensionActionResult>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServiceClient.prototype.editExtension =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/EditExtension',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_EditExtension,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.EditExtensionRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.hiddifyrpc.ExtensionActionResult>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServicePromiseClient.prototype.editExtension =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/EditExtension',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_EditExtension);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.hiddifyrpc.ExtensionRequest,
|
||||
* !proto.hiddifyrpc.ExtensionActionResult>}
|
||||
*/
|
||||
const methodDescriptor_ExtensionHostService_SubmitForm = new grpc.web.MethodDescriptor(
|
||||
'/hiddifyrpc.ExtensionHostService/SubmitForm',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.hiddifyrpc.ExtensionRequest,
|
||||
proto.hiddifyrpc.ExtensionActionResult,
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.hiddifyrpc.ExtensionActionResult.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.hiddifyrpc.ExtensionActionResult)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.hiddifyrpc.ExtensionActionResult>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServiceClient.prototype.submitForm =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/SubmitForm',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_SubmitForm,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.hiddifyrpc.ExtensionActionResult>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServicePromiseClient.prototype.submitForm =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/SubmitForm',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_SubmitForm);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.hiddifyrpc.ExtensionRequest,
|
||||
* !proto.hiddifyrpc.ExtensionActionResult>}
|
||||
*/
|
||||
const methodDescriptor_ExtensionHostService_Cancel = new grpc.web.MethodDescriptor(
|
||||
'/hiddifyrpc.ExtensionHostService/Cancel',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.hiddifyrpc.ExtensionRequest,
|
||||
proto.hiddifyrpc.ExtensionActionResult,
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.hiddifyrpc.ExtensionActionResult.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.hiddifyrpc.ExtensionActionResult)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.hiddifyrpc.ExtensionActionResult>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServiceClient.prototype.cancel =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/Cancel',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_Cancel,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.hiddifyrpc.ExtensionActionResult>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServicePromiseClient.prototype.cancel =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/Cancel',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_Cancel);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.hiddifyrpc.ExtensionRequest,
|
||||
* !proto.hiddifyrpc.ExtensionActionResult>}
|
||||
*/
|
||||
const methodDescriptor_ExtensionHostService_Stop = new grpc.web.MethodDescriptor(
|
||||
'/hiddifyrpc.ExtensionHostService/Stop',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.hiddifyrpc.ExtensionRequest,
|
||||
proto.hiddifyrpc.ExtensionActionResult,
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.hiddifyrpc.ExtensionActionResult.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.hiddifyrpc.ExtensionActionResult)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.hiddifyrpc.ExtensionActionResult>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServiceClient.prototype.stop =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/Stop',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_Stop,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.hiddifyrpc.ExtensionActionResult>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServicePromiseClient.prototype.stop =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/Stop',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_Stop);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.hiddifyrpc.ExtensionRequest,
|
||||
* !proto.hiddifyrpc.ExtensionActionResult>}
|
||||
*/
|
||||
const methodDescriptor_ExtensionHostService_GetUI = new grpc.web.MethodDescriptor(
|
||||
'/hiddifyrpc.ExtensionHostService/GetUI',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.hiddifyrpc.ExtensionRequest,
|
||||
proto.hiddifyrpc.ExtensionActionResult,
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.hiddifyrpc.ExtensionActionResult.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.hiddifyrpc.ExtensionActionResult)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.hiddifyrpc.ExtensionActionResult>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServiceClient.prototype.getUI =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/GetUI',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_GetUI,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.hiddifyrpc.ExtensionRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.hiddifyrpc.ExtensionActionResult>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.hiddifyrpc.ExtensionHostServicePromiseClient.prototype.getUI =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/hiddifyrpc.ExtensionHostService/GetUI',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_ExtensionHostService_GetUI);
|
||||
};
|
||||
|
||||
|
||||
module.exports = proto.hiddifyrpc;
|
||||
|
||||
1253
extension/html/rpc/extension_pb.js
Normal file
1253
extension/html/rpc/extension_pb.js
Normal file
File diff suppressed because it is too large
Load Diff
200
extension/html/rpc/formRenderer.js
Normal file
200
extension/html/rpc/formRenderer.js
Normal file
@@ -0,0 +1,200 @@
|
||||
const { client } = require('./client.js');
|
||||
const extension = require("./extension_grpc_web_pb.js");
|
||||
|
||||
function renderForm(json, dialog, submitAction, cancelAction, stopAction) {
|
||||
const container = document.getElementById(`extension-page-container${dialog}`);
|
||||
const formId = `dynamicForm${json.id}${dialog}`;
|
||||
|
||||
const existingForm = document.getElementById(formId);
|
||||
if (existingForm) {
|
||||
existingForm.remove();
|
||||
}
|
||||
const form = document.createElement('form');
|
||||
form.id = formId;
|
||||
|
||||
if (dialog === "dialog") {
|
||||
document.getElementById("modalLabel").textContent = json.title;
|
||||
} else {
|
||||
const titleElement = createTitleElement(json);
|
||||
form.appendChild(titleElement);
|
||||
}
|
||||
addElementsToForm(form, json);
|
||||
const buttonGroup = createButtonGroup(json, submitAction, cancelAction, stopAction);
|
||||
if (dialog === "dialog") {
|
||||
document.getElementById("modal-footer").innerHTML = '';
|
||||
document.getElementById("modal-footer").appendChild(buttonGroup);
|
||||
} else {
|
||||
form.appendChild(buttonGroup);
|
||||
}
|
||||
container.appendChild(form);
|
||||
}
|
||||
|
||||
function addElementsToForm(form, json) {
|
||||
|
||||
|
||||
|
||||
const description = document.createElement('p');
|
||||
description.textContent = json.description;
|
||||
form.appendChild(description);
|
||||
|
||||
json.fields.forEach(field => {
|
||||
const formGroup = createFormGroup(field);
|
||||
form.appendChild(formGroup);
|
||||
});
|
||||
|
||||
|
||||
return form;
|
||||
}
|
||||
|
||||
function createTitleElement(json) {
|
||||
const title = document.createElement('h1');
|
||||
title.textContent = json.title;
|
||||
return title;
|
||||
}
|
||||
|
||||
function createFormGroup(field) {
|
||||
const formGroup = document.createElement('div');
|
||||
formGroup.classList.add('mb-3');
|
||||
|
||||
if (field.label && !field.labelHidden) {
|
||||
const label = document.createElement('label');
|
||||
label.textContent = field.label;
|
||||
label.setAttribute('for', field.key);
|
||||
formGroup.appendChild(label);
|
||||
}
|
||||
|
||||
const input = createInputElement(field);
|
||||
formGroup.appendChild(input);
|
||||
return formGroup;
|
||||
}
|
||||
|
||||
function createInputElement(field) {
|
||||
let input;
|
||||
|
||||
switch (field.type) {
|
||||
case "TextArea":
|
||||
input = document.createElement('textarea');
|
||||
input.rows = field.lines || 3;
|
||||
input.textContent = field.value || '';
|
||||
break;
|
||||
|
||||
case "Checkbox":
|
||||
case "RadioButton":
|
||||
input = createCheckboxOrRadioGroup(field);
|
||||
break;
|
||||
|
||||
case "Switch":
|
||||
input = createSwitchElement(field);
|
||||
break;
|
||||
|
||||
case "Select":
|
||||
input = document.createElement('select');
|
||||
field.items.forEach(item => {
|
||||
const option = document.createElement('option');
|
||||
option.value = item.value;
|
||||
option.text = item.label;
|
||||
input.appendChild(option);
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
input = document.createElement('input');
|
||||
input.type = field.type.toLowerCase();
|
||||
input.value = field.value;
|
||||
break;
|
||||
}
|
||||
|
||||
input.id = field.key;
|
||||
input.name = field.key;
|
||||
if (field.readOnly) input.readOnly = true;
|
||||
if (field.type == "Checkbox" || field.type == "RadioButton" || field.type == "Switch") {
|
||||
|
||||
} else {
|
||||
if (field.required) input.required = true;
|
||||
input.classList.add('form-control');
|
||||
if (field.placeholder) input.placeholder = field.placeholder;
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
function createCheckboxOrRadioGroup(field) {
|
||||
const wrapper = document.createDocumentFragment();
|
||||
|
||||
field.items.forEach(item => {
|
||||
const inputWrapper = document.createElement('div');
|
||||
inputWrapper.classList.add('form-check');
|
||||
|
||||
const input = document.createElement('input');
|
||||
input.type = field.type === "Checkbox" ? 'checkbox' : 'radio';
|
||||
input.classList.add('form-check-input');
|
||||
input.id = `${field.key}_${item.value}`;
|
||||
input.name = field.key; // Grouping by name for radio buttons
|
||||
input.value = item.value;
|
||||
input.checked = field.value === item.value;
|
||||
|
||||
const itemLabel = document.createElement('label');
|
||||
itemLabel.classList.add('form-check-label');
|
||||
itemLabel.setAttribute('for', input.id);
|
||||
itemLabel.textContent = item.label;
|
||||
|
||||
inputWrapper.appendChild(input);
|
||||
inputWrapper.appendChild(itemLabel);
|
||||
wrapper.appendChild(inputWrapper);
|
||||
});
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
function createSwitchElement(field) {
|
||||
const switchWrapper = document.createElement('div');
|
||||
switchWrapper.classList.add('form-check', 'form-switch');
|
||||
|
||||
const input = document.createElement('input');
|
||||
input.type = 'checkbox';
|
||||
input.classList.add('form-check-input');
|
||||
input.setAttribute('role', 'switch');
|
||||
input.id = field.key;
|
||||
input.checked = field.value === "true";
|
||||
|
||||
const label = document.createElement('label');
|
||||
label.classList.add('form-check-label');
|
||||
label.setAttribute('for', field.key);
|
||||
label.textContent = field.label;
|
||||
|
||||
switchWrapper.appendChild(input);
|
||||
switchWrapper.appendChild(label);
|
||||
|
||||
return switchWrapper;
|
||||
}
|
||||
|
||||
function createButtonGroup(json, submitAction, cancelAction, stopAction) {
|
||||
const buttonGroup = document.createElement('div');
|
||||
buttonGroup.classList.add('btn-group');
|
||||
|
||||
const cancelButton = document.createElement('button');
|
||||
cancelButton.textContent = "Cancel";
|
||||
cancelButton.classList.add('btn', 'btn-secondary');
|
||||
cancelButton.addEventListener('click', cancelAction);
|
||||
buttonGroup.appendChild(cancelButton);
|
||||
if (stopAction != undefined) {
|
||||
const stopButton = document.createElement('button');
|
||||
stopButton.textContent = "Stop";
|
||||
stopButton.classList.add('btn', 'btn-danger');
|
||||
stopButton.addEventListener('click', stopAction);
|
||||
buttonGroup.appendChild(stopButton);
|
||||
}
|
||||
|
||||
if (json.buttonMode === "SubmitCancel") {
|
||||
const submitButton = document.createElement('button');
|
||||
submitButton.textContent = "Submit";
|
||||
submitButton.classList.add('btn', 'btn-primary');
|
||||
submitButton.addEventListener('click', submitAction);
|
||||
buttonGroup.appendChild(submitButton);
|
||||
}
|
||||
|
||||
|
||||
return buttonGroup;
|
||||
}
|
||||
|
||||
|
||||
module.exports = { renderForm };
|
||||
1221
extension/html/rpc/hiddify_grpc_web_pb.js
Normal file
1221
extension/html/rpc/hiddify_grpc_web_pb.js
Normal file
File diff suppressed because it is too large
Load Diff
5393
extension/html/rpc/hiddify_pb.js
Normal file
5393
extension/html/rpc/hiddify_pb.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user