mirror of
https://github.com/discourse/discourse.git
synced 2025-05-21 18:12:32 +08:00
DEV: Chat service object initial implementation (#19814)
This is a combined work of Martin Brennan, Loïc Guitaut, and Joffrey Jaffeux. --- This commit implements a base service object when working in chat. The documentation is available at https://discourse.github.io/discourse/chat/backend/Chat/Service.html Generating documentation has been made as part of this commit with a bigger goal in mind of generally making it easier to dive into the chat project. Working with services generally involves 3 parts: - The service object itself, which is a series of steps where few of them are specialized (model, transaction, policy) ```ruby class UpdateAge include Chat::Service::Base model :user, :fetch_user policy :can_see_user contract step :update_age class Contract attribute :age, :integer end def fetch_user(user_id:, **) User.find_by(id: user_id) end def can_see_user(guardian:, **) guardian.can_see_user(user) end def update_age(age:, **) user.update!(age: age) end end ``` - The `with_service` controller helper, handling success and failure of the service within a service and making easy to return proper response to it from the controller ```ruby def update with_service(UpdateAge) do on_success { render_serialized(result.user, BasicUserSerializer, root: "user") } end end ``` - Rspec matchers and steps inspector, improving the dev experience while creating specs for a service ```ruby RSpec.describe(UpdateAge) do subject(:result) do described_class.call(guardian: guardian, user_id: user.id, age: age) end fab!(:user) { Fabricate(:user) } fab!(:current_user) { Fabricate(:admin) } let(:guardian) { Guardian.new(current_user) } let(:age) { 1 } it { expect(user.reload.age).to eq(age) } end ``` Note in case of unexpected failure in your spec, the output will give all the relevant information: ``` 1) UpdateAge when no channel_id is given is expected to fail to find a model named 'user' Failure/Error: it { is_expected.to fail_to_find_a_model(:user) } Expected model 'foo' (key: 'result.model.user') was not found in the result object. [1/4] [model] 'user' ❌ [2/4] [policy] 'can_see_user' [3/4] [contract] 'default' [4/4] [step] 'update_age' /Users/joffreyjaffeux/Code/pr-discourse/plugins/chat/app/services/update_age.rb:32:in `fetch_user': missing keyword: :user_id (ArgumentError) from /Users/joffreyjaffeux/Code/pr-discourse/plugins/chat/app/services/base.rb:202:in `instance_exec' from /Users/joffreyjaffeux/Code/pr-discourse/plugins/chat/app/services/base.rb:202:in `call' from /Users/joffreyjaffeux/Code/pr-discourse/plugins/chat/app/services/base.rb:219:in `call' from /Users/joffreyjaffeux/Code/pr-discourse/plugins/chat/app/services/base.rb:417:in `block in run!' from /Users/joffreyjaffeux/Code/pr-discourse/plugins/chat/app/services/base.rb:417:in `each' from /Users/joffreyjaffeux/Code/pr-discourse/plugins/chat/app/services/base.rb:417:in `run!' from /Users/joffreyjaffeux/Code/pr-discourse/plugins/chat/app/services/base.rb:411:in `run' from <internal:kernel>:90:in `tap' from /Users/joffreyjaffeux/Code/pr-discourse/plugins/chat/app/services/base.rb:302:in `call' from /Users/joffreyjaffeux/Code/pr-discourse/plugins/chat/spec/services/update_age_spec.rb:15:in `block (3 levels) in <main>' ```
This commit is contained in:
1217
documentation/chat/frontend/PluginApi.html
Normal file
1217
documentation/chat/frontend/PluginApi.html
Normal file
File diff suppressed because it is too large
Load Diff
372
documentation/chat/frontend/global.html
Normal file
372
documentation/chat/frontend/global.html
Normal file
@ -0,0 +1,372 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Discourse: Global</title>
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/vendor/prism-custom.css">
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/styles.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="layout-header">
|
||||
|
||||
<h1>
|
||||
<a href="./index.html">
|
||||
Discourse
|
||||
</a>
|
||||
</h1>
|
||||
<nav class="layout-nav">
|
||||
<ul><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="PluginApi.html">PluginApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#decorateChatMessage">decorateChatMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#registerChatComposerButton">registerChatComposerButton</a></span></li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="module.exports.html">exports</a></span></li></ul><ul><li class="nav-heading">Modules</li><li class="nav-heading"><span class="nav-item-type type-module" title="module">M</span><span class="nav-item-name is-module"><a href="module-ChatApi.html">ChatApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#categoryPermissions">categoryPermissions</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channel">channel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channels">channels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannel">createChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannelArchive">createChannelArchive</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#destroyChannel">destroyChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#followChannel">followChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listChannelMemberships">listChannelMemberships</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listCurrentUserChannels">listCurrentUserChannels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#moveChannelMessages">moveChannelMessages</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#sendMessage">sendMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#unfollowChannel">unfollowChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannel">updateChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannelStatus">updateChannelStatus</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateCurrentUserChannelNotificationsSettings">updateCurrentUserChannelNotificationsSettings</a></span></li></ul><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#load">load</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#loadMore">loadMore</a></span></li>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<main class="layout-main ">
|
||||
<div class="container">
|
||||
<p class="page-kind"></p>
|
||||
<h1 class="page-title">Global</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
|
||||
<header class="not-class">
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- <h2></h2> -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<div class="container-overview">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3 class="subtitle">Methods</h3>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<article class="method">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="method-type">
|
||||
|
||||
</div>
|
||||
|
||||
<h4 class="method-name" id="load">load<span class="signature">()</span><span class="return-type-signature"> → {Promise}</span>
|
||||
</h4>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="method-description">
|
||||
|
||||
Loads first batch of results
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h4 class="method-heading">Returns</h4>
|
||||
<ul>
|
||||
|
||||
<li class="method-returns">
|
||||
|
||||
<code>Promise</code>
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h4 class="method-heading">Source</h4>
|
||||
<ul>
|
||||
<li class="method-source">
|
||||
<a href="lib_collection.js.html">lib/collection.js</a><a href="lib_collection.js.html#source.51">, line 51</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<article class="method">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="method-type">
|
||||
|
||||
</div>
|
||||
|
||||
<h4 class="method-name" id="loadMore">loadMore<span class="signature">()</span><span class="return-type-signature"> → {Promise}</span>
|
||||
</h4>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="method-description">
|
||||
|
||||
Attempts to load more results
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h4 class="method-heading">Returns</h4>
|
||||
<ul>
|
||||
|
||||
<li class="method-returns">
|
||||
|
||||
<code>Promise</code>
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h4 class="method-heading">Source</h4>
|
||||
<ul>
|
||||
<li class="method-source">
|
||||
<a href="lib_collection.js.html">lib/collection.js</a><a href="lib_collection.js.html#source.81">, line 81</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="layout-footer">
|
||||
<div class="container">
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.0</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
|
||||
<script src="scripts/prism.dev.js"></script>
|
||||
</body>
|
||||
</html>
|
80
documentation/chat/frontend/index.html
Normal file
80
documentation/chat/frontend/index.html
Normal file
@ -0,0 +1,80 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Discourse: </title>
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/vendor/prism-custom.css">
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/styles.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="layout-header">
|
||||
|
||||
<h1>
|
||||
<a href="./index.html">
|
||||
Discourse
|
||||
</a>
|
||||
</h1>
|
||||
<nav class="layout-nav">
|
||||
<ul><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="PluginApi.html">PluginApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#decorateChatMessage">decorateChatMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#registerChatComposerButton">registerChatComposerButton</a></span></li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="module.exports.html">exports</a></span></li></ul><ul><li class="nav-heading">Modules</li><li class="nav-heading"><span class="nav-item-type type-module" title="module">M</span><span class="nav-item-name is-module"><a href="module-ChatApi.html">ChatApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#categoryPermissions">categoryPermissions</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channel">channel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channels">channels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannel">createChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannelArchive">createChannelArchive</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#destroyChannel">destroyChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#followChannel">followChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listChannelMemberships">listChannelMemberships</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listCurrentUserChannels">listCurrentUserChannels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#moveChannelMessages">moveChannelMessages</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#sendMessage">sendMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#unfollowChannel">unfollowChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannel">updateChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannelStatus">updateChannelStatus</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateCurrentUserChannelNotificationsSettings">updateCurrentUserChannelNotificationsSettings</a></span></li></ul><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#load">load</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#loadMore">loadMore</a></span></li>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<main class="layout-main ">
|
||||
<div class="container">
|
||||
<p class="page-kind"></p>
|
||||
<h1 class="page-title"></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3> </h3>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section class="readme">
|
||||
<article><p>This plugin is still in active development and may change frequently</p>
|
||||
<h2>Documentation</h2>
|
||||
<p>The Discourse Chat plugin adds chat functionality to your Discourse so it can natively support both long-form and short-form communication needs of your online community.</p>
|
||||
<p>For user documentation, see <a href="https://meta.discourse.org/t/discourse-chat/230881">Discourse Chat</a>.</p>
|
||||
<p>For developer documentation, see <a href="https://discourse.github.io/discourse/">Discourse Documentation</a>.</p></article>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="layout-footer">
|
||||
<div class="container">
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.0</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
|
||||
<script src="scripts/prism.dev.js"></script>
|
||||
</body>
|
||||
</html>
|
178
documentation/chat/frontend/lib_collection.js.html
Normal file
178
documentation/chat/frontend/lib_collection.js.html
Normal file
@ -0,0 +1,178 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Discourse: lib/collection.js</title>
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/vendor/prism-custom.css">
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/styles.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="layout-header">
|
||||
|
||||
<h1>
|
||||
<a href="./index.html">
|
||||
Discourse
|
||||
</a>
|
||||
</h1>
|
||||
<nav class="layout-nav">
|
||||
<ul><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="PluginApi.html">PluginApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#decorateChatMessage">decorateChatMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#registerChatComposerButton">registerChatComposerButton</a></span></li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="module.exports.html">exports</a></span></li></ul><ul><li class="nav-heading">Modules</li><li class="nav-heading"><span class="nav-item-type type-module" title="module">M</span><span class="nav-item-name is-module"><a href="module-ChatApi.html">ChatApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#categoryPermissions">categoryPermissions</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channel">channel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channels">channels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannel">createChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannelArchive">createChannelArchive</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#destroyChannel">destroyChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#followChannel">followChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listChannelMemberships">listChannelMemberships</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listCurrentUserChannels">listCurrentUserChannels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#moveChannelMessages">moveChannelMessages</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#sendMessage">sendMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#unfollowChannel">unfollowChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannel">updateChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannelStatus">updateChannelStatus</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateCurrentUserChannelNotificationsSettings">updateCurrentUserChannelNotificationsSettings</a></span></li></ul><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#load">load</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#loadMore">loadMore</a></span></li>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<main class="layout-main layout-content--source">
|
||||
<div class="container">
|
||||
<p class="page-kind">source</p>
|
||||
<h1 class="page-title">lib/collection.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre id="source" class="source-page line-numbers"><code class="language-js">import { ajax } from "discourse/lib/ajax";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { bind } from "discourse-common/utils/decorators";
|
||||
import { Promise } from "rsvp";
|
||||
|
||||
/**
|
||||
* Handles a paginated API response.
|
||||
*/
|
||||
export default class Collection {
|
||||
@tracked items = [];
|
||||
@tracked meta = {};
|
||||
@tracked loading = false;
|
||||
|
||||
constructor(resourceURL, handler) {
|
||||
this._resourceURL = resourceURL;
|
||||
this._handler = handler;
|
||||
this._fetchedAll = false;
|
||||
}
|
||||
|
||||
get loadMoreURL() {
|
||||
return this.meta.load_more_url;
|
||||
}
|
||||
|
||||
get totalRows() {
|
||||
return this.meta.total_rows;
|
||||
}
|
||||
|
||||
get length() {
|
||||
return this.items.length;
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
|
||||
[Symbol.iterator]() {
|
||||
let index = 0;
|
||||
|
||||
return {
|
||||
next: () => {
|
||||
if (index < this.items.length) {
|
||||
return { value: this.items[index++], done: false };
|
||||
} else {
|
||||
return { done: true };
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads first batch of results
|
||||
* @returns {Promise}
|
||||
*/
|
||||
@bind
|
||||
load(params = {}) {
|
||||
this._fetchedAll = false;
|
||||
|
||||
if (this.loading) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
|
||||
const filteredQueryParams = Object.entries(params).filter(
|
||||
([, v]) => v !== undefined
|
||||
);
|
||||
const queryString = new URLSearchParams(filteredQueryParams).toString();
|
||||
|
||||
const endpoint = this._resourceURL + (queryString ? `?${queryString}` : "");
|
||||
return this.#fetch(endpoint)
|
||||
.then((result) => {
|
||||
this.items = this._handler(result);
|
||||
this.meta = result.meta;
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to load more results
|
||||
* @returns {Promise}
|
||||
*/
|
||||
@bind
|
||||
loadMore() {
|
||||
let promise = Promise.resolve();
|
||||
|
||||
if (this.loading) {
|
||||
return promise;
|
||||
}
|
||||
|
||||
if (
|
||||
this._fetchedAll ||
|
||||
(this.totalRows && this.items.length >= this.totalRows)
|
||||
) {
|
||||
return promise;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
|
||||
if (this.loadMoreURL) {
|
||||
promise = this.#fetch(this.loadMoreURL).then((result) => {
|
||||
const newItems = this._handler(result);
|
||||
|
||||
if (newItems.length) {
|
||||
this.items = this.items.concat(newItems);
|
||||
} else {
|
||||
this._fetchedAll = true;
|
||||
}
|
||||
this.meta = result.meta;
|
||||
});
|
||||
}
|
||||
|
||||
return promise.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
#fetch(url) {
|
||||
return ajax(url, { type: "GET" });
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="layout-footer">
|
||||
<div class="container">
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.0</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
|
||||
<script src="scripts/prism.dev.js"></script>
|
||||
</body>
|
||||
</html>
|
3236
documentation/chat/frontend/module-ChatApi.html
Normal file
3236
documentation/chat/frontend/module-ChatApi.html
Normal file
File diff suppressed because it is too large
Load Diff
198
documentation/chat/frontend/module.exports.html
Normal file
198
documentation/chat/frontend/module.exports.html
Normal file
@ -0,0 +1,198 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Discourse: exports</title>
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/vendor/prism-custom.css">
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/styles.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="layout-header">
|
||||
|
||||
<h1>
|
||||
<a href="./index.html">
|
||||
Discourse
|
||||
</a>
|
||||
</h1>
|
||||
<nav class="layout-nav">
|
||||
<ul><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="PluginApi.html">PluginApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#decorateChatMessage">decorateChatMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#registerChatComposerButton">registerChatComposerButton</a></span></li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="module.exports.html">exports</a></span></li></ul><ul><li class="nav-heading">Modules</li><li class="nav-heading"><span class="nav-item-type type-module" title="module">M</span><span class="nav-item-name is-module"><a href="module-ChatApi.html">ChatApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#categoryPermissions">categoryPermissions</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channel">channel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channels">channels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannel">createChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannelArchive">createChannelArchive</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#destroyChannel">destroyChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#followChannel">followChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listChannelMemberships">listChannelMemberships</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listCurrentUserChannels">listCurrentUserChannels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#moveChannelMessages">moveChannelMessages</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#sendMessage">sendMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#unfollowChannel">unfollowChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannel">updateChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannelStatus">updateChannelStatus</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateCurrentUserChannelNotificationsSettings">updateCurrentUserChannelNotificationsSettings</a></span></li></ul><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#load">load</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#loadMore">loadMore</a></span></li>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<main class="layout-main ">
|
||||
<div class="container">
|
||||
<p class="page-kind">Class</p>
|
||||
<h1 class="page-title">exports</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
|
||||
<header class="class">
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- <h2>exports</h2> -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="class-description">Handles a paginated API response.</div>
|
||||
|
||||
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<div class="container-overview">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3 class="subtitle">Constructor</h3>
|
||||
|
||||
|
||||
<div class="method-type">
|
||||
|
||||
</div>
|
||||
|
||||
<h4 class="method-name" id="exports">new exports<span class="signature">()</span><span class="return-type-signature"></span>
|
||||
</h4>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h4 class="method-heading">Source</h4>
|
||||
<ul>
|
||||
<li class="method-source">
|
||||
<a href="lib_collection.js.html">lib/collection.js</a><a href="lib_collection.js.html#source.9">, line 9</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="layout-footer">
|
||||
<div class="container">
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.0</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
|
||||
<script src="scripts/prism.dev.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,156 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Discourse: pre-initializers/chat-plugin-api.js</title>
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/vendor/prism-custom.css">
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/styles.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="layout-header">
|
||||
|
||||
<h1>
|
||||
<a href="./index.html">
|
||||
Discourse
|
||||
</a>
|
||||
</h1>
|
||||
<nav class="layout-nav">
|
||||
<ul><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="PluginApi.html">PluginApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#decorateChatMessage">decorateChatMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#registerChatComposerButton">registerChatComposerButton</a></span></li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="module.exports.html">exports</a></span></li></ul><ul><li class="nav-heading">Modules</li><li class="nav-heading"><span class="nav-item-type type-module" title="module">M</span><span class="nav-item-name is-module"><a href="module-ChatApi.html">ChatApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#categoryPermissions">categoryPermissions</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channel">channel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channels">channels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannel">createChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannelArchive">createChannelArchive</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#destroyChannel">destroyChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#followChannel">followChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listChannelMemberships">listChannelMemberships</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listCurrentUserChannels">listCurrentUserChannels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#moveChannelMessages">moveChannelMessages</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#sendMessage">sendMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#unfollowChannel">unfollowChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannel">updateChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannelStatus">updateChannelStatus</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateCurrentUserChannelNotificationsSettings">updateCurrentUserChannelNotificationsSettings</a></span></li></ul><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#load">load</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#loadMore">loadMore</a></span></li>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<main class="layout-main layout-content--source">
|
||||
<div class="container">
|
||||
<p class="page-kind">source</p>
|
||||
<h1 class="page-title">pre-initializers/chat-plugin-api.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre id="source" class="source-page line-numbers"><code class="language-js">import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
import {
|
||||
addChatMessageDecorator,
|
||||
resetChatMessageDecorators,
|
||||
} from "discourse/plugins/chat/discourse/components/chat-message";
|
||||
import { registerChatComposerButton } from "discourse/plugins/chat/discourse/lib/chat-composer-buttons";
|
||||
|
||||
/**
|
||||
* Class exposing the javascript API available to plugins and themes.
|
||||
* @class PluginApi
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback used to decorate a chat message
|
||||
*
|
||||
* @callback PluginApi~decorateChatMessageCallback
|
||||
* @param {ChatMessage} chatMessage - model
|
||||
* @param {HTMLElement} messageContainer - DOM node
|
||||
* @param {ChatChannel} chatChannel - model
|
||||
*/
|
||||
|
||||
/**
|
||||
* Decorate a chat message
|
||||
*
|
||||
* @memberof PluginApi
|
||||
* @instance
|
||||
* @function decorateChatMessage
|
||||
* @param {PluginApi~decorateChatMessageCallback} decorator
|
||||
* @example
|
||||
*
|
||||
* api.decorateChatMessage((chatMessage, messageContainer) => {
|
||||
* messageContainer.dataset.foo = chatMessage.id;
|
||||
* });
|
||||
*/
|
||||
|
||||
/**
|
||||
* Register a button in the chat composer
|
||||
*
|
||||
* @memberof PluginApi
|
||||
* @instance
|
||||
* @function registerChatComposerButton
|
||||
* @param {Object} options
|
||||
* @param {number} options.id - The id of the button
|
||||
* @param {function} options.action - An action name or an anonymous function called when the button is pressed, eg: "onFooClicked" or `() => { console.log("clicked") }`
|
||||
* @param {string} options.icon - A valid font awesome icon name, eg: "far fa-image"
|
||||
* @param {string} options.label - Text displayed on the button, a translatable key, eg: "foo.bar"
|
||||
* @param {string} options.translatedLabel - Text displayed on the button, a string, eg: "Add gifs"
|
||||
* @param {string} [options.position] - Can be "inline" or "dropdown", defaults to "inline"
|
||||
* @param {string} [options.title] - Title attribute of the button, a translatable key, eg: "foo.bar"
|
||||
* @param {string} [options.translatedTitle] - Title attribute of the button, a string, eg: "Add gifs"
|
||||
* @param {string} [options.ariaLabel] - aria-label attribute of the button, a translatable key, eg: "foo.bar"
|
||||
* @param {string} [options.translatedAriaLabel] - aria-label attribute of the button, a string, eg: "Add gifs"
|
||||
* @param {string} [options.classNames] - Additional names to add to the button’s class attribute, eg: ["foo", "bar"]
|
||||
* @param {boolean} [options.displayed] - Hide or show the button
|
||||
* @param {boolean} [options.disabled] - Sets the disabled attribute on the button
|
||||
* @param {number} [options.priority] - An integer defining the order of the buttons, higher comes first, eg: `700`
|
||||
* @param {Array.<string>} [options.dependentKeys] - List of property names which should trigger a refresh of the buttons when changed, eg: `["foo.bar", "bar.baz"]`
|
||||
* @example
|
||||
*
|
||||
* api.registerChatComposerButton({
|
||||
* id: "foo",
|
||||
* displayed() {
|
||||
* return this.site.mobileView && this.canAttachUploads;
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: "chat-plugin-api",
|
||||
after: "inject-discourse-objects",
|
||||
|
||||
initialize() {
|
||||
withPluginApi("1.2.0", (api) => {
|
||||
const apiPrototype = Object.getPrototypeOf(api);
|
||||
|
||||
if (!apiPrototype.hasOwnProperty("decorateChatMessage")) {
|
||||
Object.defineProperty(apiPrototype, "decorateChatMessage", {
|
||||
value(decorator) {
|
||||
addChatMessageDecorator(decorator);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!apiPrototype.hasOwnProperty("registerChatComposerButton")) {
|
||||
Object.defineProperty(apiPrototype, "registerChatComposerButton", {
|
||||
value(button) {
|
||||
registerChatComposerButton(button);
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown() {
|
||||
resetChatMessageDecorators();
|
||||
},
|
||||
};
|
||||
</code></pre>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="layout-footer">
|
||||
<div class="container">
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.0</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
|
||||
<script src="scripts/prism.dev.js"></script>
|
||||
</body>
|
||||
</html>
|
57
documentation/chat/frontend/scripts/prism-linenumbers.js
Normal file
57
documentation/chat/frontend/scripts/prism-linenumbers.js
Normal file
@ -0,0 +1,57 @@
|
||||
(function() {
|
||||
|
||||
if (typeof self === 'undefined' || !self.Prism || !self.document) {
|
||||
return;
|
||||
}
|
||||
|
||||
Prism.hooks.add('complete', function (env) {
|
||||
if (!env.code) {
|
||||
return;
|
||||
}
|
||||
|
||||
// works only for <code> wrapped inside <pre> (not inline)
|
||||
var pre = env.element.parentNode;
|
||||
var clsReg = /\s*\bline-numbers\b\s*/;
|
||||
if (
|
||||
!pre || !/pre/i.test(pre.nodeName) ||
|
||||
// Abort only if nor the <pre> nor the <code> have the class
|
||||
(!clsReg.test(pre.className) && !clsReg.test(env.element.className))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (env.element.querySelector(".line-numbers-rows")) {
|
||||
// Abort if line numbers already exists
|
||||
return;
|
||||
}
|
||||
|
||||
if (clsReg.test(env.element.className)) {
|
||||
// Remove the class "line-numbers" from the <code>
|
||||
env.element.className = env.element.className.replace(clsReg, '');
|
||||
}
|
||||
if (!clsReg.test(pre.className)) {
|
||||
// Add the class "line-numbers" to the <pre>
|
||||
pre.className += ' line-numbers';
|
||||
}
|
||||
|
||||
var match = env.code.match(/\n(?!$)/g);
|
||||
var linesNum = match ? match.length + 1 : 1;
|
||||
var lineNumbersWrapper;
|
||||
|
||||
var lines = new Array(linesNum + 1);
|
||||
lines = lines.join('<span></span>');
|
||||
|
||||
lineNumbersWrapper = document.createElement('span');
|
||||
lineNumbersWrapper.setAttribute('aria-hidden', 'true');
|
||||
lineNumbersWrapper.className = 'line-numbers-rows';
|
||||
lineNumbersWrapper.innerHTML = lines;
|
||||
|
||||
if (pre.hasAttribute('data-start')) {
|
||||
pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
|
||||
}
|
||||
|
||||
env.element.appendChild(lineNumbersWrapper);
|
||||
|
||||
});
|
||||
|
||||
}());
|
1115
documentation/chat/frontend/scripts/prism.dev.js
Normal file
1115
documentation/chat/frontend/scripts/prism.dev.js
Normal file
File diff suppressed because it is too large
Load Diff
325
documentation/chat/frontend/services_chat-api.js.html
Normal file
325
documentation/chat/frontend/services_chat-api.js.html
Normal file
@ -0,0 +1,325 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Discourse: services/chat-api.js</title>
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/vendor/prism-custom.css">
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="styles/styles.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header class="layout-header">
|
||||
|
||||
<h1>
|
||||
<a href="./index.html">
|
||||
Discourse
|
||||
</a>
|
||||
</h1>
|
||||
<nav class="layout-nav">
|
||||
<ul><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="PluginApi.html">PluginApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#decorateChatMessage">decorateChatMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="PluginApi.html#registerChatComposerButton">registerChatComposerButton</a></span></li><li class="nav-heading"><span class="nav-item-type type-class" title="class">C</span><span class="nav-item-name is-class"><a href="module.exports.html">exports</a></span></li></ul><ul><li class="nav-heading">Modules</li><li class="nav-heading"><span class="nav-item-type type-module" title="module">M</span><span class="nav-item-name is-module"><a href="module-ChatApi.html">ChatApi</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#categoryPermissions">categoryPermissions</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channel">channel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#channels">channels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannel">createChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#createChannelArchive">createChannelArchive</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#destroyChannel">destroyChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#followChannel">followChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listChannelMemberships">listChannelMemberships</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#listCurrentUserChannels">listCurrentUserChannels</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#moveChannelMessages">moveChannelMessages</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#sendMessage">sendMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#unfollowChannel">unfollowChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannel">updateChannel</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateChannelStatus">updateChannelStatus</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="module-ChatApi.html#updateCurrentUserChannelNotificationsSettings">updateCurrentUserChannelNotificationsSettings</a></span></li></ul><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#load">load</a></span></li><li class="nav-item"><span class="nav-item-type type-function" title="function">F</span><span class="nav-item-name is-function"><a href="global.html#loadMore">loadMore</a></span></li>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
<main class="layout-main layout-content--source">
|
||||
<div class="container">
|
||||
<p class="page-kind">source</p>
|
||||
<h1 class="page-title">services/chat-api.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre id="source" class="source-page line-numbers"><code class="language-js">import Service, { inject as service } from "@ember/service";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import UserChatChannelMembership from "discourse/plugins/chat/discourse/models/user-chat-channel-membership";
|
||||
import Collection from "../lib/collection";
|
||||
|
||||
/**
|
||||
* Chat API service. Provides methods to interact with the chat API.
|
||||
*
|
||||
* @module ChatApi
|
||||
* @implements {@ember/service}
|
||||
*/
|
||||
export default class ChatApi extends Service {
|
||||
@service chatChannelsManager;
|
||||
|
||||
/**
|
||||
* Get a channel by its ID.
|
||||
* @param {number} channelId - The ID of the channel.
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* this.chatApi.channel(1).then(channel => { ... })
|
||||
*/
|
||||
channel(channelId) {
|
||||
return this.#getRequest(`/channels/${channelId}`).then((result) =>
|
||||
this.chatChannelsManager.store(result.channel)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all accessible category channels of the current user.
|
||||
* @returns {Collection}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* this.chatApi.channels.then(channels => { ... })
|
||||
*/
|
||||
channels() {
|
||||
return new Collection(`${this.#basePath}/channels`, (response) => {
|
||||
return response.channels.map((channel) =>
|
||||
this.chatChannelsManager.store(channel)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves messages from one channel to another.
|
||||
* @param {number} channelId - The ID of the original channel.
|
||||
* @param {object} data - Params of the move.
|
||||
* @param {Array.<number>} data.message_ids - IDs of the moved messages.
|
||||
* @param {number} data.destination_channel_id - ID of the channel where the messages are moved to.
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* this.chatApi
|
||||
* .moveChannelMessages(1, {
|
||||
* message_ids: [2, 3],
|
||||
* destination_channel_id: 4,
|
||||
* }).then(() => { ... })
|
||||
*/
|
||||
moveChannelMessages(channelId, data = {}) {
|
||||
return this.#postRequest(`/channels/${channelId}/messages/moves`, {
|
||||
move: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a channel.
|
||||
* @param {number} channelId - The ID of the channel.
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* this.chatApi.destroyChannel(1).then(() => { ... })
|
||||
*/
|
||||
destroyChannel(channelId) {
|
||||
return this.#deleteRequest(`/channels/${channelId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a channel.
|
||||
* @param {object} data - Params of the channel.
|
||||
* @param {string} data.name - The name of the channel.
|
||||
* @param {string} data.chatable_id - The category of the channel.
|
||||
* @param {string} data.description - The description of the channel.
|
||||
* @param {boolean} [data.auto_join_users] - Should users join this channel automatically.
|
||||
* @returns {Promise}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* this.chatApi
|
||||
* .createChannel({ name: "foo", chatable_id: 1, description "bar" })
|
||||
* .then((channel) => { ... })
|
||||
*/
|
||||
createChannel(data = {}) {
|
||||
return this.#postRequest("/channels", { channel: data }).then((response) =>
|
||||
this.chatChannelsManager.store(response.channel)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists chat permissions for a category.
|
||||
* @param {number} categoryId - ID of the category.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
categoryPermissions(categoryId) {
|
||||
return this.#getRequest(`/category-chatables/${categoryId}/permissions`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message.
|
||||
* @param {number} channelId - ID of the channel.
|
||||
* @param {object} data - Params of the message.
|
||||
* @param {string} data.message - The raw content of the message in markdown.
|
||||
* @param {string} data.cooked - The cooked content of the message.
|
||||
* @param {number} [data.in_reply_to_id] - The ID of the replied-to message.
|
||||
* @param {number} [data.staged_id] - The staged ID of the message before it was persisted.
|
||||
* @param {Array.<number>} [data.upload_ids] - Array of upload ids linked to the message.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
sendMessage(channelId, data = {}) {
|
||||
return ajax(`/chat/${channelId}`, {
|
||||
ignoreUnsent: false,
|
||||
type: "POST",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a channel archive.
|
||||
* @param {number} channelId - The ID of the channel.
|
||||
* @param {object} data - Params of the archive.
|
||||
* @param {string} data.selection - "new_topic" or "existing_topic".
|
||||
* @param {string} [data.title] - Title of the topic when creating a new topic.
|
||||
* @param {string} [data.category_id] - ID of the category used when creating a new topic.
|
||||
* @param {Array.<string>} [data.tags] - tags used when creating a new topic.
|
||||
* @param {string} [data.topic_id] - ID of the topic when using an existing topic.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
createChannelArchive(channelId, data = {}) {
|
||||
return this.#postRequest(`/channels/${channelId}/archives`, {
|
||||
archive: data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a channel.
|
||||
* @param {number} channelId - The ID of the channel.
|
||||
* @param {object} data - Params of the archive.
|
||||
* @param {string} [data.description] - Description of the channel.
|
||||
* @param {string} [data.name] - Name of the channel.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
updateChannel(channelId, data = {}) {
|
||||
return this.#putRequest(`/channels/${channelId}`, { channel: data });
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the status of a channel.
|
||||
* @param {number} channelId - The ID of the channel.
|
||||
* @param {string} status - The new status, can be "open" or "closed".
|
||||
* @returns {Promise}
|
||||
*/
|
||||
updateChannelStatus(channelId, status) {
|
||||
return this.#putRequest(`/channels/${channelId}/status`, { status });
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists members of a channel.
|
||||
* @param {number} channelId - The ID of the channel.
|
||||
* @returns {Collection}
|
||||
*/
|
||||
listChannelMemberships(channelId) {
|
||||
return new Collection(
|
||||
`${this.#basePath}/channels/${channelId}/memberships`,
|
||||
(response) => {
|
||||
return response.memberships.map((membership) =>
|
||||
UserChatChannelMembership.create(membership)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists public and direct message channels of the current user.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listCurrentUserChannels() {
|
||||
return this.#getRequest("/channels/me").then((result) => {
|
||||
return (result?.channels || []).map((channel) =>
|
||||
this.chatChannelsManager.store(channel)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes current user follow a channel.
|
||||
* @param {number} channelId - The ID of the channel.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
followChannel(channelId) {
|
||||
return this.#postRequest(`/channels/${channelId}/memberships/me`).then(
|
||||
(result) => UserChatChannelMembership.create(result.membership)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes current user unfollow a channel.
|
||||
* @param {number} channelId - The ID of the channel.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
unfollowChannel(channelId) {
|
||||
return this.#deleteRequest(`/channels/${channelId}/memberships/me`).then(
|
||||
(result) => UserChatChannelMembership.create(result.membership)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update notifications settings of current user for a channel.
|
||||
* @param {number} channelId - The ID of the channel.
|
||||
* @param {object} data - The settings to modify.
|
||||
* @param {boolean} [data.muted] - Mutes the channel.
|
||||
* @param {string} [data.desktop_notification_level] - Notifications level on desktop: never, mention or always.
|
||||
* @param {string} [data.mobile_notification_level] - Notifications level on mobile: never, mention or always.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
updateCurrentUserChannelNotificationsSettings(channelId, data = {}) {
|
||||
return this.#putRequest(
|
||||
`/channels/${channelId}/notifications-settings/me`,
|
||||
{ notifications_settings: data }
|
||||
);
|
||||
}
|
||||
|
||||
get #basePath() {
|
||||
return "/chat/api";
|
||||
}
|
||||
|
||||
#getRequest(endpoint, data = {}) {
|
||||
return ajax(`${this.#basePath}${endpoint}`, {
|
||||
type: "GET",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
#putRequest(endpoint, data = {}) {
|
||||
return ajax(`${this.#basePath}${endpoint}`, {
|
||||
type: "PUT",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
#postRequest(endpoint, data = {}) {
|
||||
return ajax(`${this.#basePath}${endpoint}`, {
|
||||
type: "POST",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
#deleteRequest(endpoint, data = {}) {
|
||||
return ajax(`${this.#basePath}${endpoint}`, {
|
||||
type: "DELETE",
|
||||
data,
|
||||
});
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="layout-footer">
|
||||
<div class="container">
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.0</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
|
||||
<script src="scripts/prism.dev.js"></script>
|
||||
</body>
|
||||
</html>
|
498
documentation/chat/frontend/styles/styles.css
Normal file
498
documentation/chat/frontend/styles/styles.css
Normal file
@ -0,0 +1,498 @@
|
||||
:root {
|
||||
--primary-color: #0664a8;
|
||||
--secondary-color: #107e7d;
|
||||
--link-color: var(--primary-color);
|
||||
--link-hover-color: var(--primary-color);
|
||||
--border-color: #eee;
|
||||
--code-color: #666;
|
||||
--code-attention-color: #ca2d00;
|
||||
--text-color: #4a4a4a;
|
||||
--light-font-color: #999;
|
||||
--supporting-color: #7097b5;
|
||||
--heading-color: var(--text-color);
|
||||
--subheading-color: var(--secondary-color);
|
||||
--heading-background: #f7f7f7;
|
||||
--code-bg-color: #f8f8f8;
|
||||
--nav-title-color: var(--primary-color);
|
||||
--nav-title-align: center;
|
||||
--nav-title-size: 1rem;
|
||||
--nav-title-margin-bottom: 1.5em;
|
||||
--nav-title-font-weight: 600;
|
||||
--nav-list-margin-left: 2em;
|
||||
--nav-bg-color: #fff;
|
||||
--nav-heading-display: block;
|
||||
--nav-heading-color: #aaa;
|
||||
--nav-link-color: #666;
|
||||
--nav-text-color: #aaa;
|
||||
--nav-type-class-color: #fff;
|
||||
--nav-type-class-bg: #FF8C00;
|
||||
--nav-type-member-color: #39b739;
|
||||
--nav-type-member-bg: #d5efd5;
|
||||
--nav-type-function-color: #549ab9;
|
||||
--nav-type-function-bg: #e1f6ff;
|
||||
--nav-type-namespace-color: #eb6420;
|
||||
--nav-type-namespace-bg: #fad8c7;
|
||||
--nav-type-typedef-color: #964cb1;
|
||||
--nav-type-typedef-bg: #f2e4f7;
|
||||
--nav-type-module-color: #964cb1;
|
||||
--nav-type-module-bg: #f2e4f7;
|
||||
--nav-type-event-color: #948b34;
|
||||
--nav-type-event-bg: #fff6a6;
|
||||
--max-content-width: 900px;
|
||||
--nav-width: 320px;
|
||||
--padding-unit: 30px;
|
||||
--layout-footer-color: #aaa;
|
||||
--member-name-signature-display: none;
|
||||
--base-font-size: 16px;
|
||||
--base-line-height: 1.7;
|
||||
--body-font: -apple-system, system-ui, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
--code-font: Consolas, Monaco, "Andale Mono", monospace;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--body-font);
|
||||
font-size: var(--base-font-size);
|
||||
line-height: var(--base-line-height);
|
||||
color: var(--text-color);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: var(--link-color);
|
||||
}
|
||||
a:hover, a:active {
|
||||
text-decoration: underline;
|
||||
color: var(--link-hover-color);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
img + p {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
tt, code, kbd, samp {
|
||||
font-family: var(--code-font);
|
||||
}
|
||||
|
||||
code {
|
||||
display: inline-block;
|
||||
background-color: var(--code-bg-color);
|
||||
padding: 2px 6px 0px;
|
||||
border-radius: 3px;
|
||||
color: var(--code-attention-color);
|
||||
}
|
||||
|
||||
.prettyprint.source code:not([class*=language-]) {
|
||||
display: block;
|
||||
padding: 20px;
|
||||
overflow: scroll;
|
||||
color: var(--code-color);
|
||||
}
|
||||
|
||||
.layout-main,
|
||||
.layout-footer {
|
||||
margin-left: var(--nav-width);
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: var(--max-content-width);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.layout-main {
|
||||
margin-top: var(--padding-unit);
|
||||
margin-bottom: var(--padding-unit);
|
||||
padding: 0 var(--padding-unit);
|
||||
}
|
||||
|
||||
.layout-header {
|
||||
background: var(--nav-bg-color);
|
||||
border-right: 1px solid var(--border-color);
|
||||
position: fixed;
|
||||
padding: 0 var(--padding-unit);
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: var(--nav-width);
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
.layout-header h1 {
|
||||
display: block;
|
||||
margin-bottom: var(--nav-title-margin-bottom);
|
||||
font-size: var(--nav-title-size);
|
||||
font-weight: var(--nav-title-font-weight);
|
||||
text-align: var(--nav-title-align);
|
||||
}
|
||||
.layout-header h1 a:link, .layout-header h1 a:visited {
|
||||
color: var(--nav-title-color);
|
||||
}
|
||||
.layout-header img {
|
||||
max-width: 120px;
|
||||
display: block;
|
||||
margin: 1em auto;
|
||||
}
|
||||
|
||||
.layout-nav {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.layout-nav ul {
|
||||
margin: 0 0 var(--nav-list-margin-left);
|
||||
padding: 0;
|
||||
}
|
||||
.layout-nav li {
|
||||
list-style-type: none;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
.layout-nav li.nav-heading:first-child {
|
||||
display: var(--nav-heading-display);
|
||||
margin-left: 0;
|
||||
margin-bottom: 1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--nav-heading-color);
|
||||
font-size: 0.85em;
|
||||
}
|
||||
.layout-nav a {
|
||||
color: var(--nav-link-color);
|
||||
}
|
||||
.layout-nav a:link, .layout-nav a a:visited {
|
||||
color: var(--nav-link-color);
|
||||
}
|
||||
|
||||
.layout-content--source {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.nav-heading {
|
||||
margin-top: 1em;
|
||||
font-weight: 500;
|
||||
}
|
||||
.nav-heading a {
|
||||
color: var(--nav-link-color);
|
||||
}
|
||||
.nav-heading a:link, .nav-heading a:visited {
|
||||
color: var(--nav-link-color);
|
||||
}
|
||||
.nav-heading .nav-item-type {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.nav-item-type {
|
||||
display: inline-block;
|
||||
font-size: 0.9em;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
line-height: 1.2em;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
border-radius: 0.2em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
.nav-item-type.type-class {
|
||||
color: var(--nav-type-class-color);
|
||||
background: var(--nav-type-class-bg);
|
||||
}
|
||||
.nav-item-type.type-typedef {
|
||||
color: var(--nav-type-typedef-color);
|
||||
background: var(--nav-type-typedef-bg);
|
||||
}
|
||||
.nav-item-type.type-function {
|
||||
color: var(--nav-type-function-color);
|
||||
background: var(--nav-type-function-bg);
|
||||
}
|
||||
.nav-item-type.type-namespace {
|
||||
color: var(--nav-type-namespace-color);
|
||||
background: var(--nav-type-namespace-bg);
|
||||
}
|
||||
.nav-item-type.type-member {
|
||||
color: var(--nav-type-member-color);
|
||||
background: var(--nav-type-member-bg);
|
||||
}
|
||||
.nav-item-type.type-module {
|
||||
color: var(--nav-type-module-color);
|
||||
background: var(--nav-type-module-bg);
|
||||
}
|
||||
.nav-item-type.type-event {
|
||||
color: var(--nav-type-event-color);
|
||||
background: var(--nav-type-event-bg);
|
||||
}
|
||||
|
||||
.nav-item-name.is-function:after {
|
||||
display: inline;
|
||||
content: "()";
|
||||
color: var(--nav-link-color);
|
||||
opacity: 0.75;
|
||||
}
|
||||
.nav-item-name.is-class {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.layout-footer {
|
||||
padding-top: 2rem;
|
||||
padding-bottom: 2rem;
|
||||
font-size: 0.8em;
|
||||
text-align: center;
|
||||
color: var(--layout-footer-color);
|
||||
}
|
||||
.layout-footer a {
|
||||
color: var(--light-font-color);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
color: var(--heading-color);
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
font-size: 1em;
|
||||
}
|
||||
h5 + .code-caption {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.page-kind {
|
||||
margin: 0 0 -0.5em;
|
||||
font-weight: 400;
|
||||
color: var(--light-font-color);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-weight: 600;
|
||||
font-size: 1.5em;
|
||||
color: var(--subheading-color);
|
||||
margin: 1em 0;
|
||||
padding: 0.4em 0;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
.subtitle + .event, .subtitle + .member, .subtitle + .method {
|
||||
border-top: none;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.method-type + .method-name {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.event-name,
|
||||
.member-name,
|
||||
.method-name,
|
||||
.type-definition-name {
|
||||
margin: 1em 0;
|
||||
font-size: 1.4rem;
|
||||
font-family: var(--code-font);
|
||||
font-weight: 600;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.event-name .signature-attributes,
|
||||
.member-name .signature-attributes,
|
||||
.method-name .signature-attributes,
|
||||
.type-definition-name .signature-attributes {
|
||||
display: inline-block;
|
||||
margin-left: 0.25em;
|
||||
font-size: 60%;
|
||||
color: #999;
|
||||
font-style: italic;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.type-signature {
|
||||
display: inline-block;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.member-name .type-signature {
|
||||
display: var(--member-name-signature-display);
|
||||
}
|
||||
|
||||
.type-signature,
|
||||
.return-type-signature {
|
||||
color: #aaa;
|
||||
font-weight: 400;
|
||||
}
|
||||
.type-signature a:link, .type-signature a:visited,
|
||||
.return-type-signature a:link,
|
||||
.return-type-signature a:visited {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
table {
|
||||
margin-top: 1rem;
|
||||
width: auto;
|
||||
min-width: 400px;
|
||||
max-width: 100%;
|
||||
border-top: 1px solid var(--border-color);
|
||||
border-right: 1px solid var(--border-color);
|
||||
}
|
||||
table th, table h4 {
|
||||
font-weight: 500;
|
||||
}
|
||||
table th,
|
||||
table td {
|
||||
padding: 0.5rem 0.75rem;
|
||||
}
|
||||
table th,
|
||||
table td {
|
||||
border-left: 1px solid var(--border-color);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
table p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.readme h2 {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
margin: 1em 0;
|
||||
padding-bottom: 0.5rem;
|
||||
color: var(--subheading-color);
|
||||
}
|
||||
.readme h2 + h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
.readme h3 {
|
||||
margin: 2rem 0 1rem 0;
|
||||
}
|
||||
|
||||
article.event, article.member, article.method {
|
||||
padding: 1em 0 1em;
|
||||
margin: 1em 0;
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.method-type-signature:not(:empty) {
|
||||
display: inline-block;
|
||||
background: #ecf0f1;
|
||||
color: #627475;
|
||||
padding: 0.25em 0.5em 0.35em;
|
||||
font-weight: 300;
|
||||
font-size: 0.8rem;
|
||||
margin: 0 0.75em 0 0;
|
||||
}
|
||||
|
||||
.method-heading {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
li.method-returns,
|
||||
.method-params li {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.method-source a:link, .method-source a:visited {
|
||||
color: var(--light-font-color);
|
||||
}
|
||||
|
||||
.method-returns p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.event-description,
|
||||
.method-description {
|
||||
margin: 0 0 2em;
|
||||
}
|
||||
|
||||
.param-type code,
|
||||
.method-returns code {
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.param-name {
|
||||
font-weight: 600;
|
||||
display: inline-block;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.param-type,
|
||||
.param-default,
|
||||
.param-attributes {
|
||||
font-family: var(--code-font);
|
||||
}
|
||||
|
||||
.param-default::before {
|
||||
display: inline-block;
|
||||
content: "Default:";
|
||||
font-family: var(--body-font);
|
||||
}
|
||||
|
||||
.param-attributes {
|
||||
color: var(--light-font-color);
|
||||
}
|
||||
|
||||
.param-description p:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.param-properties {
|
||||
font-weight: 500;
|
||||
margin: 1em 0 0;
|
||||
}
|
||||
|
||||
.param-types,
|
||||
.property-types {
|
||||
display: inline-block;
|
||||
margin: 0 0.5em 0 0.25em;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.param-attr,
|
||||
.property-attr {
|
||||
display: inline-block;
|
||||
padding: 0.2em 0.5em;
|
||||
border: 1px solid #eee;
|
||||
color: #aaa;
|
||||
font-weight: 300;
|
||||
font-size: 0.8em;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.properties-table p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
pre[class*=language-] {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
code[class*=language-],
|
||||
pre[class*=language-] {
|
||||
text-shadow: none;
|
||||
border: none;
|
||||
}
|
||||
code[class*=language-].source-page,
|
||||
pre[class*=language-].source-page {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.line-numbers .line-numbers-rows {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.source-page {
|
||||
font-size: 14px;
|
||||
}
|
||||
.source-page code {
|
||||
z-index: 1;
|
||||
}
|
||||
.source-page .line-height.temporary {
|
||||
z-index: 0;
|
||||
}
|
142
documentation/chat/frontend/styles/vendor/prism-custom.css
vendored
Normal file
142
documentation/chat/frontend/styles/vendor/prism-custom.css
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
/* PrismJS 1.17.1
|
||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+http */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
font-size: 1em;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f6f8fa;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
Reference in New Issue
Block a user