Add Windows save instructions UI and fix URL #296
- Add Windows instruction dialog when saving scripts for Windows. - Fix incorrect macOS download URL given for Linux instructions. - Refactor UI rendering, eleminating the use of `v-html` and JavaScript variables to hold HTML code.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<span class="code-wrapper">
|
||||
<span class="dollar">$</span>
|
||||
<code ref="codeElement"><slot /></code>
|
||||
<div class="copy-action-container">
|
||||
<TooltipWrapper>
|
||||
<FlatButton icon="copy" @click="copyCode" />
|
||||
<template #tooltip>
|
||||
Copy
|
||||
</template>
|
||||
</TooltipWrapper>
|
||||
</div>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, shallowRef } from 'vue';
|
||||
import TooltipWrapper from '@/presentation/components/Shared/TooltipWrapper.vue';
|
||||
import { injectKey } from '@/presentation/injectionSymbols';
|
||||
import FlatButton from '@/presentation/components/Shared/FlatButton.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
TooltipWrapper,
|
||||
FlatButton,
|
||||
},
|
||||
setup() {
|
||||
const { copyText } = injectKey((keys) => keys.useClipboard);
|
||||
|
||||
const codeElementRef = shallowRef<HTMLElement | undefined>();
|
||||
|
||||
async function copyCode() {
|
||||
const element = codeElementRef.value;
|
||||
if (!element) {
|
||||
throw new Error('Code element could not be found.');
|
||||
}
|
||||
const code = element.textContent;
|
||||
if (!code) {
|
||||
throw new Error('Code element does not contain any text.');
|
||||
}
|
||||
await copyText(code);
|
||||
}
|
||||
|
||||
return {
|
||||
copyCode,
|
||||
codeElement: codeElementRef,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/presentation/assets/styles/main" as *;
|
||||
|
||||
.code-wrapper {
|
||||
display: inline-flex;
|
||||
white-space: nowrap;
|
||||
justify-content: space-between;
|
||||
font-family: $font-normal;
|
||||
background-color: $color-primary-darker;
|
||||
color: $color-on-primary;
|
||||
align-items: center;
|
||||
padding: 0.2rem;
|
||||
.dollar {
|
||||
margin-right: 0.5rem;
|
||||
font-size: 0.8rem;
|
||||
user-select: none;
|
||||
}
|
||||
.copy-action-container {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
code {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<li class="step">
|
||||
<slot />
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'InstructionSteps', // Define component name for empty component for Vue build and ESLint compatibility.
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.step {
|
||||
margin: 10px 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<ol>
|
||||
<slot />
|
||||
</ol>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'InstructionSteps', // Define component name for empty component for Vue build and ESLint compatibility.
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<component
|
||||
:is="component"
|
||||
v-if="component"
|
||||
:filename="filename"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { injectKey } from '@/presentation/injectionSymbols';
|
||||
import { OperatingSystem } from '@/domain/OperatingSystem';
|
||||
import MacOsInstructions from './Platforms/MacOsInstructions.vue';
|
||||
import LinuxInstructions from './Platforms/LinuxInstructions.vue';
|
||||
import WindowsInstructions from './Platforms/WindowsInstructions.vue';
|
||||
import type { Component } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
filename: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const { currentState } = injectKey((keys) => keys.useCollectionState);
|
||||
|
||||
const component = computed<Component>(() => getInstructionsComponent(
|
||||
currentState.value.collection.os,
|
||||
));
|
||||
|
||||
return {
|
||||
component,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
function getInstructionsComponent(operatingSystem: OperatingSystem): Component {
|
||||
switch (operatingSystem) {
|
||||
case OperatingSystem.macOS:
|
||||
return MacOsInstructions;
|
||||
case OperatingSystem.Linux:
|
||||
return LinuxInstructions;
|
||||
case OperatingSystem.Windows:
|
||||
return WindowsInstructions;
|
||||
default:
|
||||
throw new Error(`No instructions for the operating system: ${OperatingSystem[operatingSystem]}`);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<InstructionSteps>
|
||||
<InstructionStep>
|
||||
Download the file.
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
You should have already been prompted to save the script file.
|
||||
</p>
|
||||
<p>
|
||||
If this was not the case or you did not save the script when prompted,
|
||||
please try to download your script file again.
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
Open terminal.
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
Opening terminal changes based on the distro you run.
|
||||
</p>
|
||||
<p>
|
||||
You may search for "Terminal" in your application launcher to find it.
|
||||
</p>
|
||||
<p>
|
||||
Alternatively use terminal shortcut for your distro if it has one by default:
|
||||
<ul>
|
||||
<li>
|
||||
<code>Ctrl-Alt-T</code>:
|
||||
Ubuntu, CentOS, Linux Mint, Elementary OS, ubermix, Kali…
|
||||
</li>
|
||||
<li>
|
||||
<code>Super-T</code>: Pop!_OS…
|
||||
</li>
|
||||
<li>
|
||||
<code>Alt-T</code>: Parrot OS…
|
||||
</li>
|
||||
<li>
|
||||
<code>Ctrl-Alt-Insert</code>: Bodhi Linux…
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
<p>
|
||||
Navigate to the folder where you downloaded the file e.g.:
|
||||
</p>
|
||||
<p>
|
||||
<CopyableCommand>
|
||||
cd ~/Downloads
|
||||
</CopyableCommand>
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
Press on <code>enter/return</code> key after running the command.
|
||||
</p>
|
||||
<p>
|
||||
If the file is not downloaded on Downloads folder,
|
||||
change <code>Downloads</code> to path where the file is downloaded.
|
||||
</p>
|
||||
<p>
|
||||
This command means:
|
||||
<ul>
|
||||
<li><code>cd</code> will change the current folder.</li>
|
||||
<li><code>~</code> is the user home directory.</li>
|
||||
</ul>
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</p>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
<p>
|
||||
Give the file execute permissions:
|
||||
</p>
|
||||
<p>
|
||||
<CopyableCommand>
|
||||
chmod +x {{ filename }}
|
||||
</CopyableCommand>
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
Press on <code>enter/return</code> key after running the command.
|
||||
</p>
|
||||
<p>
|
||||
It will make the file executable.
|
||||
</p>
|
||||
<p>
|
||||
If you use desktop environment you can alternatively (instead of running the command):
|
||||
<ol>
|
||||
<li>Locate the file using your file manager.</li>
|
||||
<li>Right click on the file, select "Properties".</li>
|
||||
<li>Go to "Permissions" and check "Allow executing file as program".</li>
|
||||
</ol>
|
||||
</p>
|
||||
<p>
|
||||
These GUI steps and name of options may change depending on your file manager.'
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</p>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
<p>
|
||||
Execute the file:
|
||||
</p>
|
||||
<p>
|
||||
<CopyableCommand>
|
||||
./{{ filename }}
|
||||
</CopyableCommand>
|
||||
<InfoTooltip>
|
||||
If you have desktop environment, instead of running this command you can alternatively:
|
||||
<ol>
|
||||
<li>Locate the file using your file manager.</li>
|
||||
<li>Right click on the file, select "Run as program".</li>
|
||||
</ol>
|
||||
</InfoTooltip>
|
||||
</p>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
If asked, enter your administrator password.
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
As you type, your password will be hidden but the keys are still
|
||||
registered, so keep typing.
|
||||
</p>
|
||||
<p>
|
||||
Press on <code>enter/return</code> key after typing your password.
|
||||
</p>
|
||||
<p>
|
||||
Administrator privileges are required to configure OS.
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
</InstructionSteps>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import InstructionSteps from '../InstructionSteps.vue';
|
||||
import InstructionStep from '../InstructionStep.vue';
|
||||
import InfoTooltip from '../../InfoTooltip.vue';
|
||||
import CopyableCommand from '../CopyableCommand.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
CopyableCommand,
|
||||
InfoTooltip,
|
||||
InstructionSteps,
|
||||
InstructionStep,
|
||||
},
|
||||
props: {
|
||||
filename: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<InstructionSteps>
|
||||
<InstructionStep>
|
||||
Download the file.
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
You should have already been prompted to save the script file.
|
||||
</p>
|
||||
<p>
|
||||
If this was not the case or you did not save the script when prompted,
|
||||
please try to download your script file again.
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
Open terminal.
|
||||
<InfoTooltip>
|
||||
Type Terminal into Spotlight or open it from the Applications -> Utilities folder.
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
<p>
|
||||
Navigate to the folder where you downloaded the file e.g.:
|
||||
</p>
|
||||
<p>
|
||||
<CopyableCommand>
|
||||
cd ~/Downloads
|
||||
</CopyableCommand>
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
Press on <code>enter/return</code> key after running the command.
|
||||
</p>
|
||||
<p>
|
||||
If the file is not downloaded on Downloads folder,
|
||||
change <code>Downloads</code> to path where the file is downloaded.
|
||||
</p>
|
||||
<p>
|
||||
This command means:
|
||||
<ul>
|
||||
<li><code>cd</code> will change the current folder.</li>
|
||||
<li><code>~</code> is the user home directory.</li>
|
||||
</ul>
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</p>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
<p>
|
||||
Give the file execute permissions:
|
||||
</p>
|
||||
<p>
|
||||
<CopyableCommand>
|
||||
chmod +x {{ filename }}
|
||||
</CopyableCommand>
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
Press on <code>enter/return</code> key after running the command.
|
||||
</p>
|
||||
<p>
|
||||
It will make the file executable.
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</p>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
<p>
|
||||
Execute the file:
|
||||
</p>
|
||||
<p>
|
||||
<CopyableCommand>
|
||||
./{{ filename }}
|
||||
</CopyableCommand>
|
||||
<InfoTooltip>
|
||||
Alternatively you can locate the file in <strong>Finder</strong> and double click on it.
|
||||
</InfoTooltip>
|
||||
</p>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
If asked, enter your administrator password.
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
As you type, your password will be hidden but the keys are
|
||||
still registered, so keep typing.
|
||||
</p>
|
||||
<p>
|
||||
Press on <code>enter/return</code> key after typing your password.
|
||||
</p>
|
||||
<p>
|
||||
Administrator privileges are required to configure OS.
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
</InstructionSteps>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import InstructionSteps from '../InstructionSteps.vue';
|
||||
import InstructionStep from '../InstructionStep.vue';
|
||||
import InfoTooltip from '../../InfoTooltip.vue';
|
||||
import CopyableCommand from '../CopyableCommand.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
CopyableCommand,
|
||||
InfoTooltip,
|
||||
InstructionSteps,
|
||||
InstructionStep,
|
||||
},
|
||||
props: {
|
||||
filename: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<InstructionSteps>
|
||||
<InstructionStep>
|
||||
Download the file.
|
||||
<InfoTooltip>
|
||||
<p>If a save prompt doesn't appear, try downloading the script again.</p>
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
If warned by your browser, keep the file.
|
||||
<InfoTooltip>
|
||||
<!--
|
||||
Tests (15/01/2023):
|
||||
- Edge (Defender activated): "filename isn't commonly downloaded..."
|
||||
- Chrome: No warning, downloads directly.
|
||||
- Firefox: No warning, downloads directly.
|
||||
-->
|
||||
<p>
|
||||
Browsers may warn you when downloading scripts.
|
||||
</p>
|
||||
<p>
|
||||
privacy.sexy scripts are verified to be safe and are dedicated to securing your privacy.
|
||||
</p>
|
||||
<p>
|
||||
In <strong>Edge</strong>:
|
||||
<ol>
|
||||
<li>Select <strong>Keep</strong> from the downloads section.</li>
|
||||
<li>Click <strong>Show more</strong> on the next warning.</li>
|
||||
<li>Select <strong>Keep anyway</strong>.</li>
|
||||
</ol>
|
||||
</p>
|
||||
<p>
|
||||
For <strong>Firefox</strong> and <strong>Chrome</strong>, typically no additional
|
||||
action is needed.
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
If your antivirus (e.g., Defender) alerts you, address the warning.
|
||||
<InfoTooltip>
|
||||
<!--
|
||||
Tests (15/01/2023):
|
||||
- Edge (Defender activated): "Couldn't download - Virus detected"
|
||||
- Chrome: "Virus detected"
|
||||
- Firefox: Does not trigger false-positive on Defender somehow.
|
||||
-->
|
||||
<p>
|
||||
Depending on the script, antivirus software may incorrectly flag the download as a threat.
|
||||
</p>
|
||||
<p>
|
||||
These false positives are common for scripts that modify system settings.
|
||||
</p>
|
||||
<p>
|
||||
To handle false warnings in Microsoft Defender:
|
||||
<ol>
|
||||
<li>Open <strong>Virus & threat protection</strong> from the Start menu.</li>
|
||||
<li>
|
||||
Locate the event in <strong>Protection history</strong>
|
||||
that pertains to the script.
|
||||
</li>
|
||||
<li>In the event details, select <strong>Actions</strong> > <strong>Allow</strong>.</li>
|
||||
<li>If the script was deleted, please re-download it.</li>
|
||||
</ol>
|
||||
</p>
|
||||
<blockquote>
|
||||
<strong>Caution:</strong> For your security, remember to:
|
||||
<ul>
|
||||
<li>Only allow scripts from trusted sources.</li>
|
||||
<li>Avoid broad exclusions in your antivirus settings.</li>
|
||||
<li>Keep real-time protection enabled whenever possible.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
<!--
|
||||
Tests (15/01/2023):
|
||||
- Edge (Defender activated): No prompts
|
||||
- Chrome: No prompts
|
||||
- Firefox: "filename is executable file. Executable files may contain..?" OK/Cancel
|
||||
-->
|
||||
Open the downloaded file.
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
Confirm any browser prompts to open the file.
|
||||
</p>
|
||||
<p>
|
||||
This standard security measure ensures that you are aware of the script execution.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Firefox</strong> users, click <strong>OK</strong> to acknowledge the
|
||||
executable file warning.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Edge</strong> and <strong>Chrome</strong> users usually will not
|
||||
encounter additional prompts.
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
If prompted, confirm SmartScreen warnings.
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
Windows SmartScreen might display a cautionary message.
|
||||
</p>
|
||||
<p>
|
||||
This happens since privacy.sexy scripts are not recognized
|
||||
by Microsoft's certification process.
|
||||
</p>
|
||||
<p>
|
||||
<ol>
|
||||
<li>Select <strong>More info</strong>.</li>
|
||||
<li>Select <strong>Run anyway</strong>.</li>
|
||||
</ol>
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
<InstructionStep>
|
||||
If administrative permissions are requested, grant them.
|
||||
<InfoTooltip>
|
||||
<p>
|
||||
The script may request administrative rights to apply changes.
|
||||
</p>
|
||||
<p>
|
||||
This is necessary for the script to apply the intended privacy settings.
|
||||
</p>
|
||||
<p>
|
||||
Click <strong>Yes</strong> to authorize and run the script.
|
||||
</p>
|
||||
</InfoTooltip>
|
||||
</InstructionStep>
|
||||
</InstructionSteps>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import InstructionSteps from '../InstructionSteps.vue';
|
||||
import InstructionStep from '../InstructionStep.vue';
|
||||
import InfoTooltip from '../../InfoTooltip.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
InfoTooltip,
|
||||
InstructionSteps,
|
||||
InstructionStep,
|
||||
},
|
||||
props: {
|
||||
filename: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user