Skip to content

Commit

Permalink
first working release
Browse files Browse the repository at this point in the history
  • Loading branch information
svelle committed Mar 26, 2021
1 parent 2dfdec7 commit a0b5aa2
Show file tree
Hide file tree
Showing 8 changed files with 286 additions and 33 deletions.
163 changes: 163 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions plugin.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"id": "com.mattermost.plugin-starter-template",
"name": "Plugin Starter Template",
"description": "This plugin serves as a starting point for writing a Mattermost plugin.",
"homepage_url": "https://github.com/mattermost/mattermost-plugin-starter-template",
"support_url": "https://github.com/mattermost/mattermost-plugin-starter-template/issues",
"release_notes_url": "https://github.com/mattermost/mattermost-plugin-starter-template/releases/tag/v0.1.0",
"id": "com.svelle.mattermost-spoiler-plugin",
"name": "Spoiler Plugin",
"description": "Allows users to post using the /spoiler command for hiding potential spoilers from other users in a channel",
"homepage_url": "https://github.com/svelle/mattermost-spoiler-plugin",
"support_url": "https://github.com/svelle/mattermost-spoiler-plugin/issues",
"release_notes_url": "",
"icon_path": "assets/starter-template-icon.svg",
"version": "0.1.0",
"min_server_version": "5.12.0",
Expand Down
9 changes: 6 additions & 3 deletions server/manifest.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 74 additions & 2 deletions server/plugin.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package main

import (
"encoding/json"
"fmt"
"net/http"
"strings"
"sync"

"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/plugin"
)

Expand All @@ -20,9 +23,78 @@ type Plugin struct {
configuration *configuration
}

// ServeHTTP demonstrates a plugin that handles HTTP requests by greeting the world.
func (p *Plugin) OnActivate() (err error) {
err = p.API.RegisterCommand(&model.Command{
Trigger: "spoiler",
DisplayName: "Spoiler Text",
Description: "hides text from others until they click to reveal it",
AutoComplete: true,
AutoCompleteDesc: "type what you want to hide from others",
})
return
}

func (p *Plugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, world!")
userId := r.Header.Get("Mattermost-User-Id")
w.WriteHeader(200)
if userId == "" {
return
}

var action_data model.PostActionIntegrationRequest
decoder := json.NewDecoder(r.Body)
encoder := json.NewEncoder(w)
defer r.Body.Close()
if err := decoder.Decode(&action_data); err != nil {
encoder.Encode(&model.PostActionIntegrationResponse{
EphemeralText: err.Error(),
})
return
}

url := fmt.Sprintf("/plugins/%s/show", manifest.Id)
if r.RequestURI != url {
encoder.Encode(&model.PostActionIntegrationResponse{
EphemeralText: r.RequestURI,
})
return
}
if post, err := p.API.GetPost(action_data.PostId); err != nil {
encoder.Encode(&model.PostActionIntegrationResponse{
EphemeralText: err.Error(),
})
return
} else {
if text, ok := post.Props["spoiler_text"]; ok {
encoder.Encode(&model.PostActionIntegrationResponse{
EphemeralText: text.(string),
})
}
}
}

func (p *Plugin) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
output := fmt.Sprintf("This is a hidden message. Click Show to reveal")
spoilered_text := strings.TrimPrefix(args.Command, "/spoiler ")
resp := &model.CommandResponse{
ResponseType: model.COMMAND_RESPONSE_TYPE_IN_CHANNEL,
Text: output,
Type: "custom_spoiler",
Props: model.StringInterface{
"spoiler_text": spoilered_text,
"attachments": []*model.SlackAttachment{{
Actions: []*model.PostAction{{
Integration: &model.PostActionIntegration{
Context: model.StringInterface{},
URL: fmt.Sprintf("%s/plugins/%s/show", args.SiteURL, manifest.Id),
},
Type: model.POST_ACTION_TYPE_BUTTON,
Name: "Show",
},
}}},
},
}
return resp, nil
}

// See https://developers.mattermost.com/extend/plugins/server/reference/
20 changes: 0 additions & 20 deletions server/plugin_test.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,8 @@
package main

import (
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"
)

func TestServeHTTP(t *testing.T) {
assert := assert.New(t)
plugin := Plugin{}
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/", nil)

plugin.ServeHTTP(nil, w, r)

result := w.Result()
assert.NotNil(result)
defer result.Body.Close()
bodyBytes, err := ioutil.ReadAll(result.Body)
assert.Nil(err)
bodyString := string(bodyBytes)

assert.Equal("Hello, world!", bodyString)
}
23 changes: 23 additions & 0 deletions webapp/src/components/spoiler_post.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import PropTypes from 'prop-types';

import "./style.scss"

const { formatText, messageHtmlToComponent } = window.PostUtils;


export default class SpoilerPost extends React.PureComponent {
static propTypes = {
post: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
}

render() {
const post = this.props.post;
if (post == null) return null;
const props = { ...(post.props || {}) };
const spoiler_text = messageHtmlToComponent(formatText(props.spoiler_text || ''));
return <div className="spoiler--wrapper">{spoiler_text}</div>;
}
}

8 changes: 8 additions & 0 deletions webapp/src/components/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.spoiler--wrapper {
filter: blur(3px) drop-shadow(0px 0px 3px black);
}

.spoiler--wrapper:hover {
transition: all 0.2s ease-in-out;
filter: none;
}
8 changes: 6 additions & 2 deletions webapp/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Store, Action} from 'redux';

import SpoilerPost from './components/spoiler_post';
import {GlobalState} from 'mattermost-redux/types/store';

import manifest from './manifest';
Expand All @@ -11,6 +11,10 @@ export default class Plugin {
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
public async initialize(registry: PluginRegistry, store: Store<GlobalState, Action<Record<string, unknown>>>) {
// @see https://developers.mattermost.com/extend/plugins/webapp/reference/
registry.registerPostTypeComponent(
'custom_spoiler',
SpoilerPost,
);
}
}

Expand All @@ -20,4 +24,4 @@ declare global {
}
}

window.registerPlugin(manifest.id, new Plugin());
window.registerPlugin(manifest.id, new Plugin());

0 comments on commit a0b5aa2

Please sign in to comment.