diff --git a/plugins-data.json b/plugins-data.json index d16b710..7d9f7ce 100644 --- a/plugins-data.json +++ b/plugins-data.json @@ -152,5 +152,34 @@ "installUrl": "https://rp.jarviscli.dev/reminders/install/", "sourceUrl": "https://github.com/everestmcarthur/revenge-plugins/tree/main/plugins/reminders", "issueUrl": "https://github.com/everestmcarthur/revenge-plugins/issues/new?title=%5BReminders%5D%20" + }, + { + "id": "view-raw", + "name": "ViewRaw", + "description": "View a message's raw JSON data - searchable, syntax-highlighted, and copyable. Fork of bwlok's ViewRaw with a crash fix and a nicer viewer.", + "authors": [ + "everestmcarthur", + "sapphire", + "Vendicated", + "Bwlok" + ], + "category": "Utility", + "status": "revived", + "accent": "#38BDF8", + "tagline": "See a message's raw JSON - searchable, syntax-highlighted, and copyable.", + "note": "Fork of bwlok's ViewRaw (GPLv3 - see the plugin's own LICENSE file). Fixed a crash that hit every message long-press, then rebuilt the viewer with search and syntax highlighting on top.", + "howItWorks": "Long-press any message and pick \"View Raw\" to see exactly what Discord sent for it - every field, not just the rendered text. The original plugin crashed the long-press menu on every message because it assumed a specific internal icon shape without checking it first; this fork guards that assumption and everything else in the same patch. The viewer itself was rebuilt: a search box highlights matching lines (dimming the rest, not hiding them, so you keep the structure for context), values are color-coded by type, and there are one-tap copy buttons for either just the message content or the full JSON.", + "features": [ + "Search box highlights matching keys/values across the whole payload", + "Syntax-colored JSON (strings, numbers, booleans, null all render differently)", + "Separate \"Copy Content\" and \"Copy JSON\" buttons", + "Crash fixed: no longer breaks the message long-press menu" + ], + "commands": [], + "limitations": "Licensed GPLv3 (inherited from the original), not the same terms as the rest of this repo - see plugins/view-raw/LICENSE.", + "pageUrl": "https://rp.jarviscli.dev/view-raw/", + "installUrl": "https://rp.jarviscli.dev/view-raw/install/", + "sourceUrl": "https://github.com/everestmcarthur/revenge-plugins/tree/main/plugins/view-raw", + "issueUrl": "https://github.com/everestmcarthur/revenge-plugins/issues/new?title=%5BViewRaw%5D%20" } ] \ No newline at end of file diff --git a/view-raw/index.html b/view-raw/index.html new file mode 100644 index 0000000..d3dce5e --- /dev/null +++ b/view-raw/index.html @@ -0,0 +1,736 @@ + + + + + +revenge-plugins + + + + + + +
+ + +
+
+ + Revenge Plugins +
+

Discord, your way.

+

A hand-built collection of plugins for Revenge, the Discord Android client mod - rebuilt from scratch where the old ecosystem broke, and net-new where nothing existed yet.

+ + +
+
+ +
+
+
+ + ⌘K +
+
+
+ +
+

+
+ +
+
+ +
+ + + +
+ +
+
+ +
+
+
+ + + + diff --git a/view-raw/install/index.js b/view-raw/install/index.js new file mode 100644 index 0000000..68e01db --- /dev/null +++ b/view-raw/install/index.js @@ -0,0 +1,2 @@ +(function(g,C,f,A,c,e,R,N){"use strict";function _(t){const n=JSON.parse(JSON.stringify(t));for(const o in n.author)switch(o){case"email":case"phone":case"mfaEnabled":case"hasBouncedEmail":delete n.author[o]}return n}const{View:T,Text:h}=e.ReactNative,l={key:"#7dd3fc",string:"#86efac",number:"#fbbf24",boolean:"#c4b5fd",null:"#9ca3af",punct:"#d1d5db"},k=/^(\s*)("(?:[^"\\]|\\.)*"\s*:\s*)?(.*)$/;function m(t){return t.startsWith('"')?l.string:/^(true|false)/.test(t)?l.boolean:/^null/.test(t)?l.null:/^-?\d/.test(t)?l.number:l.punct}function I({text:t,query:n}){const o=e.React.useMemo(function(){return t.split(` +`)},[t]),r=(n||"").trim().toLowerCase();return e.React.createElement(T,null,o.map(function(u,B){const p=u.match(k),y=p?.[1]??"",i=p?.[2],s=p?.[3]??u,d=!!r&&u.toLowerCase().includes(r),a=!!r&&!d;return e.React.createElement(h,{key:B,selectable:!0,style:{fontFamily:"monospace",fontSize:12.5,lineHeight:18,opacity:a?.35:1,backgroundColor:d?"rgba(88,101,242,0.25)":"transparent"}},y,i?e.React.createElement(h,{style:{color:l.key}},i):null,e.React.createElement(h,{style:{color:m(s)}},s))}))}const{View:v,ScrollView:x,TextInput:L,Text:b}=e.ReactNative;function O({message:t}){const[n,o]=e.React.useState(""),r=e.React.useMemo(function(){return JSON.stringify(_(t),null,4)},[t.id]);return e.React.createElement(x,{style:{flex:1,marginHorizontal:13,marginVertical:10}},e.React.createElement(v,{style:{flexDirection:"row"}},e.React.createElement(R.Button,{style:{flex:1,marginRight:8,marginBottom:8},text:"Copy Content",color:"brand",size:"small",disabled:!t.content,onPress:function(){e.clipboard.setString(t.content),N.showToast("Copied content to clipboard",f.getAssetIDByName("toast_copy_link"))}}),e.React.createElement(R.Button,{style:{flex:1,marginBottom:8},text:"Copy JSON",color:"brand",size:"small",onPress:function(){e.clipboard.setString(r),N.showToast("Copied JSON to clipboard",f.getAssetIDByName("toast_copy_link"))}})),e.React.createElement(L,{value:n,onChangeText:o,placeholder:"Search keys or values\u2026",placeholderTextColor:"#888",autoCapitalize:"none",autoCorrect:!1,style:{borderWidth:1,borderColor:"rgba(128,128,128,0.35)",borderRadius:8,paddingHorizontal:10,paddingVertical:8,marginBottom:10,color:"#fff"}}),!!t.content&&e.React.createElement(v,{style:{marginBottom:12}},e.React.createElement(b,{style:{fontSize:11,opacity:.6,marginBottom:4,fontWeight:"700"}},"MESSAGE CONTENT"),e.React.createElement(b,{selectable:!0,style:{fontFamily:"monospace",fontSize:13}},t.content)),e.React.createElement(b,{style:{fontSize:11,opacity:.6,marginBottom:4,fontWeight:"700"}},"RAW DATA"),e.React.createElement(x,{horizontal:!0,showsHorizontalScrollIndicator:!0},e.React.createElement(I,{text:r,query:n})))}const w=c.findByProps("openLazy","hideActionSheet"),E=c.findByProps("push","pushLazy","pop"),$=c.findByProps("getRenderCloseButton")?.getRenderCloseButton??c.findByProps("getHeaderCloseButton")?.getHeaderCloseButton,D=c.findByName("Navigator")??c.findByProps("Navigator")?.Navigator,{FormRow:F,FormIcon:z}=R.Forms,H=C.before("openLazy",w,function([t,n,o]){const r=o?.message;n!=="MessageLongPressActionSheet"||!r||t.then(function(u){const B=C.after("default",u,function(p,y){e.React.useEffect(function(){return function(){B()}},[]);try{const i=function(){return e.React.createElement(D,{initialRouteName:"RawPage",goBackOnBackPress:!0,screens:{RawPage:{title:"ViewRaw",headerLeft:$?.(function(){return E.pop()}),render:function(){return e.React.createElement(O,{message:r})}}}})},s=A.findInReactTree(y,function(a){return Array.isArray(a)&&a[0]?.type?.name==="ActionSheetRowGroup"}),d=A.findInReactTree(y,function(a){return a?.[0]?.type?.name==="ButtonRow"});if(d)d.push(e.React.createElement(F,{label:"View Raw",leading:e.React.createElement(z,{style:{opacity:1},source:f.getAssetIDByName("ic_chat_bubble_16px")}),onPress:function(){w.hideActionSheet(),E.push(i)}}));else if(s&&s[1]){const a=s[1],P=a?.props?.children?.[0],V=P?.type,S=P?.props?.icon;if(!V||!S||!Array.isArray(a?.props?.children))console.log("[ViewRaw] Error: Could not find ActionSheetRow/icon shape");else{const J=e.React.createElement(V,{label:"View Raw",icon:{$$typeof:S.$$typeof,type:S.type,key:null,ref:null,props:{IconComponent:function(){return e.React.createElement(z,{style:{opacity:1},source:f.getAssetIDByName("ic_chat_bubble_32px")})}}},onPress:function(){w.hideActionSheet(),E.push(i)},key:"view-raw"});a.props.children.push(J)}}else console.log("[ViewRaw] Error: Could not find ActionSheet")}catch(i){console.log("[ViewRaw] Error: Failed to add View Raw button",i)}})})});var M={onUnload:function(){return H()}};return g.default=M,Object.defineProperty(g,"__esModule",{value:!0}),g})({},vendetta.patcher,vendetta.ui.assets,vendetta.utils,vendetta.metro,vendetta.metro.common,vendetta.ui.components,vendetta.ui.toasts); diff --git a/view-raw/install/manifest.json b/view-raw/install/manifest.json new file mode 100644 index 0000000..255573c --- /dev/null +++ b/view-raw/install/manifest.json @@ -0,0 +1 @@ +{"name":"ViewRaw","description":"View a message's raw JSON data - searchable, syntax-highlighted, and copyable. Fork of bwlok's ViewRaw with a crash fix and a nicer viewer.","authors":[{"name":"everestmcarthur"},{"name":"sapphire"},{"name":"Vendicated"},{"name":"Bwlok"}],"main":"index.js","hash":"d425f783f369101e889ecec73eebc9126cbf70cc3147de96f0b71370864e9aee"} \ No newline at end of file